1. 概念
在关系型数据库中,我们经常要处理一对一 、 一对多的关系 。 例如, 一辆汽车需要有一个引擎,这是一对一的关系。 一辆汽车有 4 个或更多个轮子,这是一对多的关系 。关联元素就是专门用来处理关联关系的;
关联元素
association 一对一关系
collection 一对多关系
discriminator 鉴别器映射
关联方式
嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型
2. 一对一 嵌套结果
association标签 嵌套结果方式 常用属性:
property :对应实体类中的属性名,必填项。
javaType : 属性对应的 Java 类型 。
resultMap : 可以直接使用现有的 resultMap (直接引用对应的完整的命名空间namesapce.resultMap 的id),而不需要在这里配置映射关系。
columnPrefix :查询列的前缀,配置前缀后,在子标签配置 result 的 column 时可以省略前缀
Tips:
resultMap可以通过使用extends实现继承关系,简化很多配置工作量;
关联的表查询的类添加前缀是编程的好习惯;
通过添加完整的命名空间,可以引用其他xml文件的resultMap;
查完主表, 再查关联表的方式
association标签 嵌套查询方式 常用属性:
select :另 一个映射查询的 id, MyBatis 会额外执行这个查询获取嵌套对象的结果 。
column :列名(或别名),将主查询中列的结果作为嵌套查询的 参数。
fetchType :数据加载方式,可选值为 lazy 和 eager,分别为延迟加载和积极加载 ,这个配置会覆盖全局的 lazyLoadingEnabled 配置
Tips:“N+1 查询问题”
概括地讲,N+1 查询问题可以是这样引起的:
你执行了一个单独的 SQL 语句来获取结果列表(就是“+1”)。
对返回的每条记录,你执行了一个查询语句来为每个加载细节(就是“N”)。
这个问题会导致成百上千的 SQL 语句被执行。这通常不是期望的。
解决办法:使用“fetchType=lazy”并且全局setting进行改善:
如果没有用到关联表的数据 则不会去查询关联表, 如果要用则再查询。 按需加载
position.getName 时加载
一对多 嵌套查询
collection 支持的属性以及属性的作用和 association 完全相同
mybatis会根据id标签,进行字段的合并,合理配置好ID标签可以提高处理的效率;
Tips:
如果要配置一个相当复杂的映射,一定要从基础映射开始配置,每增加一些配置就进行对应的测试,在循序渐进的过程中更容易发现和解决问题
3.discriminator 鉴别器映射
在特定的情况下使用不同的pojo进行关联, 鉴别器元素就是被设计来处理这个情况的。鉴别器非常容易理解,因为它的表现很像 Java 语言中的 switch 语句;
discriminator 标签常用的两个属性如下:
column:该属性用于设置要进行鉴别比较值的列 。
javaType:该属性用于指定列的类型,保证使用相同的 Java 类型来比较值。
discriminator 标签可以有1个或多个 case 标签, case 标签包含以下三个属性 。
value : 该值为 discriminator 指定 column 用来匹配的值 。
resultMap : 当column的值和value的值匹配时,可以配置使用resultMap指定的映 射,resultMap优先级高于 resultType 。
resultType : 当 column 的值和 value 的值匹配时,用于配置使用 resultType指定的映射。
4.多对多
先决条件一:多对多需要一种中间表建立连接关系;
先决条件二:多对多关系是由两个一对多关系组成的,一对多可以也可以用两种方式实现;