mybatis关联

---title: mybatis关联date: 2017-12-18 18:00:30tags: - [mybatis]categories: - [编程] - [开发工具]permalink: zxh---[TOC]web项目开发中目前很多企业都是在SSM框架基础上开发。其中的M指的的mybatis(ibatis).mybatis里指的一说的是规避了传统的jdbc等的繁琐。在mybatis中我们可以只用关注sql本身。而不用太在意之个执行过程。大大简化了我们平时的开发。mybatis深究的话会有很多要说的。今天我们只来看看mybatis中提供了映射中的关联标签。# 数据准备## 数据结构下表stage_order中的stage_list是有stage表中ID组成的一个字符串,之间由逗号相隔。比如stage_list=1,2,3表示该stage_order中关联着ID为1或2或3的stage。我们得分别取查询stageID=1或2或3的stage进行实体映射展示。下一节我们看看实体的构造![表结构](http://oytmxyuek.bkt.clouddn.com/20171218_1.png)## 实体准备### 基本实体(对应stage_order单表) - 在下面的实体中出现的注解我们不需要在意,这是swagger框架的注解,在本章节中不需要理解。换句话说我们可以吧注解删掉。不会影响我们的功能的。```@ApiModel(description = "阶段顺序表")@Table(name = "STAGE_ORDER")public class StageOrder { @Id @ApiModelProperty("阶段顺序ID") @NotNull(message = "阶段顺序ID不可为空(NULL)") private Long stageOrderId; @ApiModelProperty("路口编号") @NotNull(message = "路口编号不可为空(NULL)") private Long intersectionId; @ApiModelProperty("相序名称") @NotBlank(message = "相序名称不可为空白") @ByteLength(max = 30, message = "相序名称长度不能超过{max}") private String orderName; @ApiModelProperty("阶段列表") @NotBlank(message = "阶段列表不可为空白") @ByteLength(max = 200, message = "阶段列表长度不能超过{max}") private String stageList; public Long getStageOrderId() { return stageOrderId; } public void setStageOrderId(Long stageOrderId) { this.stageOrderId = stageOrderId; } public Long getIntersectionId() { return intersectionId; } public void setIntersectionId(Long intersectionId) { this.intersectionId = intersectionId; } public String getOrderName() { return orderName; } public void setOrderName(String orderName) { this.orderName = orderName == null ? null : orderName.trim(); } public String getStageList() { return stageList; } public void setStageList(String stageList) { this.stageList = stageList == null ? null : stageList.trim(); }}```### 扩展实体```public class StageOrderDto extends StageOrder { /** * 相位列表 */ private ListstageInfoList; public ListgetStageInfoList() { return stageInfoList; } public void setStageInfoList(ListstageInfoList) { this.stageInfoList = stageInfoList; } }```#基本映射## 一对一 - 有了上面的实体和对应的Table,那么我们如何在mybatis中将Table和实体关联呢。看如下在mapper.xml中的配置`````` - 但是我们会发现resultMap中stageInfoList这个在跟数据库怎么对应呢?还有association是什么?assocaition中select又是什么?为什么assocaition中的column和上面一样? 我想对于刚接触的朋友来说心里一定会有这些疑问。 - 上面已经说了resultmap是用来衔接实体去数据库表的桥梁。resultMap中ID属性就是一个唯一性的作用。一般只需要在当前xml中唯一就行了。因为在每个xml中有`namespace`,来确定当前的mapper.xml的唯一性。 ![mapper文件的唯一性确定](http://oytmxyuek.bkt.clouddn.com/20171218_2.png) - resultMap字标签id 和result都是用来映射单列值到type对应的实体或者map中属性。在使用上ID是对应数据库中主键使用的。数据库中会有联合主键,在resultMap中就用两个ID标签对应就行了。还有一点ID也是用来做唯一标识的。当和其他对象进行比较的时候这个时候ID就有作用了。这里和数据库一样主键就是代表一条数据。这里也是同样的作用。在mybatis中有缓存机制。就是通过这个ID实现的。比如mybatis这个时候需要缓存这个对象。则以ID为key ,对象的json化为值存储到缓存中。 ## 一对多 - 这里一对多就用到了上面的BaseResultMap这个resultMap了。上面我们的讲的ID和result就是我们平时简单单表查询中的一对一关系处理。但是association就是用来关联查询的。association中文翻译就是联想的意思。在mybatis中association的作用就是在查询到STAGE_LIST这个字段的时候默认会将STAGE_LIST的值传到selectStageInfos这个查询语句中查询。传递进去是按照上面的写法我们不能用#{stage_list}取,得通过#{id}获取。这里是默认的必须用#{id}.但是一个健全的框架不会这么死板的。下面我们在介绍如何动态传递。 - association严格上来说应该是用于selectStageInfos查询获取的也是一个基本类型数据。但是在我们上面的需求描述中我们知道STAGE_LIST,对应到stage表中其实回事多条数据。所以我们在StageOrderDto中stageInfoList也是用list集合来承载的。这个时候用association不会出错。mybatis底层却不同,底层实际上是转换成了collection标签来实现的。应为collection对应的是集合的映射处理。所以追求完美的程序员在级联查询是如果级联出的是集合就用collection标签。但是两种情况用association都是可以的。## 查询应用 - 说了这么多,下面我们通过两个查询看看查询的实现代码```select

from stage_order

where INTERSECTION_ID=#{intersectionId}select

from stage

where stage_id in (#{id})```  -  当我们调用selectStageOrderDtoListByIntersectionId通过intersectionId查询到数据的时候,会在通过查询到的STAGE_LIST作为条件调用selectStageInfos这个查询语句的。在selectStageInfos中的#{id}就是selectStageOrderDtoListByIntersectionId查询到的STAGE_LIST。# 复杂映射  - 但是我们平时企业开发中光这样的查询有时候并不能满足我们的需求。常见复杂的查询有: 多重级联和联合主键查询## 多重映射  - 多重查询说白了就是多用几次级联(association或collection),对就是这个简单。这个可能有的人没有过甚至没想过。下面贴段实际的代码。因为下面代码在联合主键章节也需要用到。```PHASE_LIST,PROGRAM_ID,PROGRAM_NAME,INTERSECTION_ID,STAGE_ID,STAGE_NAME,STAGE_SEQ,GREEN,RED_YELLOW,YELLOW,ALL_RED,MIN_GREEN,MAX_GREENselect

from program where program_id=#{id}select * from (select

dp.day_plan_id,

trim(REGEXP_REPLACE(to_char(dp.time_duration,'0000'),'([[:digit:]]{2})([[:digit:]]{2})','\1:\2')) as time_duration,

pg.program_id,

pg.program_name,

so.order_name,

so.stage_order_id,

cm.control_mode_id,

cm.control_mode_name,

'120' as cycle

from day_plan dp

left join control_mode cm on dp.control_mode_id=cm.control_mode_id

left join program pg on dp.program_id=pg.program_id

left join stage_order so on dp.stage_order_id=so.stage_order_id

where dp.day_plan_no=#{dayPlanNo}

and dp.intersection_id=#{intersectionId}

)

group by (day_plan_id,time_duration,program_id,program_name,order_name,stage_order_id,control_mode_id,control_mode_name,cycle)

order by time_duration ascselect #{intersectionId} as intersection_id,week.plan_name,week.plan_id from

(

select '星期一' as plan_name,intersection_id,monday as plan_id from week_plan

union

select '星期二' as plan_name,intersection_id,tuesday as plan_id from week_plan

union

select '星期三' as plan_name,intersection_id,wendesday as plan_id from week_plan

union

select '星期四' as plan_name,intersection_id,thursday as plan_id from week_plan

union

select '星期五' as plan_name,intersection_id,friday as plan_id from week_plan

union

select '星期六' as plan_name,intersection_id,saturday as plan_id from week_plan

union

select '星期日' as plan_name,intersection_id,sunday as plan_id from week_plan

)week

left join day_plan dp on dp.day_plan_no=week.plan_id

where week.intersection_id=#{intersectionId}

group by week.plan_id,week.plan_name,week.intersection_id

order by week.plan_id```  ## 联合主键查询  - 在我们很多时候数据库中的主键并不是一个字段,而是通过两个甚至多个字段组合成主键。我们习惯上称之为联合主键。在多重映射中的代码中我们可以看到`weekProgramResultMap`中级联`selectDayPlanInfosByPlanNo`这个sql查询。但是有意思的是column中并不是我们熟悉的一个字段。而是通过花括号做首尾,中间加入多个字段组成的一个字符串。这个就是我们本章节引入的概念---联合主键级联查询。column属性值我们分析一下可以看出`intersectionId=INTERSECTION_ID`和`dayPlanNo=PLAN_ID`组成的。我们可以看成是两个map,等号前是key等号后是value。key就是我们在新的select中引用的key,及#{key}方式获取。value就是原来的select查询获得的数据。也是通过value来查询新的数据的。这里就解决了我们上面[基本映射章节](#baseMapped)说必须用#{id}的局限性。所以在上面中如何我们不想用#{id},那么需要修改column的传入风格{stageId=stage_list}就可以用#{stageId}# 简单说明  工作遇到的需求,mybatis还有很多神操作。以后有机会更新。在mybatis中映射并不是仅仅字段这么简单。还有点逗风格的引用。这些以后看时间在更新。## 常用标签# 格言人生贵知心,定交无暮早。 —— 袁中道[//]:组合关联查询:[//]:有的时候association需要关联的字段不止一个。这个时候column="{stageList=STAGE_LIST,intersectionId=INTERSECTION_ID}"[//]:然后在selectStageInfos查询中#{stageList},#{intersectionId}分别获取对应的值。但是在selectStageInfos中的参数类型得改成java.util.HashMap[//]:多关联查询:[//]:多关联就是上面的关联中在关联[//]:其中关联是用association可以,但是为了便于理解,最好在一对多用collection代替association

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • MyBatis--关联查询 当查询内容涉及到具有关联关系的多个表时,就需要使用关联查询。根据表与表间的关联关系的不...
    我可能是个假开发阅读 9,578评论 0 16
  • 针对部门信息的查询 , 表, 数据, 实体类就不重复了, 可以看上一篇 mybatis 关联表[员工对部门]员工的...
    _琳哥阅读 771评论 0 0
  • 以员工和部门表为基础的关联表查询这篇讲员工的查询先看看数据库的建表 部门表 员工表 表创建好了 , 数据就自己随便...
    _琳哥阅读 1,221评论 0 0
  • 出发的这天风和日丽,老爸步行送我们直到高速路口。 入住的酒店有升旗的时间表,距离天安门很近,方便第二天早起。 天气...
    小镇斜阳阅读 167评论 0 0
  • 丙申之年十一月,余左迁江东。月到初冬,南风更甚于前。雨落于乌天之下,隐明月于重云之边。冬雨潇寒,绵绵尽焉,此止江南...
    程石阅读 292评论 1 2