文章目录
1 关联关系概述
在实际的开发中,对数据库的操作经常是涉及到多张表。对于多表操作,MyBatis提供了关联映射,通过关联映射就可以很好地处理对象与对象之间的关联关系。
在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多。
- 一对一:在任意一方引入对方主键作为外键
- 一对多:在“多”的一方,添加“一”的一方的主键作为外键
- 多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键
在Java中,通过对象也可以进行关联关系描述:
- 一对一:在本类中定义对方发类型的对象,如果A类中定义了B类类型的属性b,B类中定义A类类型的属性a。
- 一对多:一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a。
- 多对多:在A类中定义B类类型的集合,在B类中定义A类类型的集合。
2 一对一
在Mapper文件中<resultMap>
元素中,包含一个<association>
子元素,MyBatis就是通过该元素来处理一对一关联关系的。
2.1 association可配置属性
- property:指定映射到的实体类对象属性,与表字段一一对应
- column:指定表中对应的字段
- javaType:指定映射到实体对象属性的类型
- select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询
- fetchType:指定在关联查询时是否使用延迟加载。该属性又lazy和eager两个属性值,默认值为lazy
2.2 一对一的实现方式
2.2.1 嵌套查询实现
嵌套查询是通过执行另一条SQL映射语句来返回预期的复杂类型。
- 嵌套查询是在查询SQL中嵌入一个子查询SQL
- 嵌套查询会执行多条SQL语句
- 嵌套查询SQL语句编写较为简单
2.2.1.1 优缺点
- 优点:简单
- 缺点:嵌套查询的方式要执行多条SQL语句。这对于大型数据集合和列表展示不是很好,因为这样可能会导致成白上千条关联的SQL语句被执行,从而极大的消耗数据库性能并且会降低查询效率。
解决这个缺点可以配置延迟加载,使用MyBatis的延迟加载在一定程度上可以降低运行消耗并提高查询效率。MyBatis默认没有开启延迟加载,需要自行配置:
<settings>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="false" />
<!-- 将积极加载改为消息加载,即按需加载 -->
<setting name="aggressiveLazyLoading" value="true" />
</settings>
在映射文件中<association>
元素和<collection>
元素中都已经默认配置了延迟加载属性,即默认属性fetchType = "lazy"
所以在配置文件中开启延迟加载后需要在映射文件中在做配置。推荐使用嵌套查询
2.2.1.2 配置方式
示例:
<association property="card" column="card_id" javaType="cn.edu.ujn.ch9.dao.IdCard" select="cn.edu.ujn.ch9.dao.IdCardMapper.findCodeById"/>
</association>
解释:
- property:类属性
- column:表字段
- select:嵌套的子查询
- javaType:关联属性类型
2.2.2 嵌套结果实现
嵌套结果就是使用嵌套结果映射来处理重复的联合结果的子集。
- 嵌套结果是一个嵌套的多表查询SQL
- 嵌套结果只会执行一条复杂的SQL语句
- 嵌套结果SQL语句编写是比较复杂的
2.2.2.1 配置方式
示例:
<association property="card" javaType="cn.edu.ujn.ch9.dao.IdCard">
<!-- id为类属性,card_id为表字段-->
<id property="id" column="card_id"/>
<result property="code" column="code"/>
</association>
3 一对多
在Mapper文件中<resultMap>
元素中,包含了一个<collection>
子元素,MyBatis就是通过这个子元素来处理一对多关联关系的。
3.1 collection可配置的属性
<clooection>
和<association>
元素大部分属性是相通的。
- ofType:ofType属性和javaType属性相对应,它用于指定实体对象中集合类属性所包含的元素类型
- property:指定映射到的实体类对象属性,与表字段一一对应
- column:指定表中对应字段
- JavaType:指定映射到实体对象属性的类型
- select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询
- fetchType:指定在关联查询时是否启用延迟加载,该属性又lazy和eager两个属性值,默认为lazy。
3.2 一对多的实现方式
3.2.1 嵌套查询
配置方法:
<collection property="orderList" column="id" ofType="cn.edu.ujn.ch9.dao.Orders"
select="cn.edu.ujn.ch9.dao.OrdersMapper.selectOrders">
</collection>
3.2.2 嵌套结果
配置方法:
<collection property="ordersList" ofType="cn.edu.ujn.ch9.dao.Orders">
<id property="id" column="orders_id"/>
<result property="number" column="number"/>
</collection>
4 多对多
在MyBatis中同样使用<collection>
元素处理多对多关联关系。
4.1 可配置的属性
- ofType:ofType属性与javaType属性相对应,它用于指定实体对象中集合类属性所包含的元素类型
- property:指定映射到的实体类对象属性,与表字段一一对应
- column:指定表中对应的字段
- javaType:指定映射到实体对象属性的类型
- select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询
- fetchType:指定在关联查询时是否使用延迟加载,该属性有lazy和eager两个属性值,默认为lazy。
4.2 一对多的实现方式
配置方法:
<collection property="pruductList" column="id" ofType="cn.edu.ujn.ch9.dao.Product" select="cn.edu.ujn.ch9.dao.ProductMapper.findByOrders">
</collection>
声明:
若本人发布的作品涉及版权或存在其他问题,请联系我删除。
谢谢浏览!