在实际的开发中,对数据库的操作常常会涉及多张表,这在面向对象中就涉及了对象与对象之间的关联关系。针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好地处理对象与对象之间的关联关系
9.1关联关系概述
在关系型数据库中,多表之间存在着三种关联关系,分别为一对一,一对多和多对多,这三种关联关系的具体说明如下:
(1)一对一:在任意一方引入对方主键作为外键
(2)一对多:在多的一方,添加一的一方的主键作为外键
(3)多对多:产生中间关系表,引入两种表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键
通过数据库中的表可以描述数据之间的关系,同样,在Java中,通过对象也可以进行关系描述,如表:
(1)一对一的关系:就是在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a
(2)一对多的关系:就是一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a
(3)多对多的关系:在A类中定义B类类型的集合,在B类中定义A类类型的集合
9.2一对一
在现实生活中,一对一关联关系是十分常见的;例如,一个人只能有一个身份证,同时一个人身份证也只会对应一个人。在<resultMap>
元素中,包含了一个<association>
子元素,MyBatis就是通过该元素来处理一对一关联关系的
在<association>
元素中,通常可以配置以下属性:
(1)property:指定映射到的实体类对象属性,与表字段一一对应
(2)column:指定表中对应的字段
(3)javaType:指定映射到实体对象属性的类型
(4)select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询
(5)fetchType:指定在关联查询时是否启动延迟加载。fetchType属性有lazy和eager两个属性值,默认值为lazy(即默认关系映射延迟加载)
<association>
元素的使用非常简单,只需要参考如下两种示例配置即可:
<!--方式一:嵌套查询-->
<association property="card" column="card_id"
javaType="com.itheima.po.IdCard"
select="com.itheima.mapper.IdCardMapper.findCodeById" />
<!--方式一:嵌套结果-->
<association property="card" javaType="com.itheima.po.IdCard">
<id property="id" column="card_id" />
<result property="code" column="code" />
</association>
MyBatis在映射文件中加载关联关系对象主要通过两种方式:嵌套查询和嵌套结果
嵌套查询:是指通过执行另外一条SQL映射语句来返回预期的复杂类型
嵌套结果:是使用嵌套结果映射来处理重复的联合结果的子集
9.3一对多
与一对一的关联关系相比,开发人员接触更多的关联关系是一对多(或多对一)。例如一个用户可以有多个订单,同时多个订单归一个用户所有。
在<resultMap>
元素中,包含了一个<collection>
子元素,MyBatis就是通过该元素来处理一对多关联关系的。元素中,包含<collection>
子元素的属性大部分与<association>
相同,但其还包含一个特殊属性:ofType
ofType:与javaType属性对应,它用于指定实体对象中集合类属性包含的元素类型
<collection>
元素的使用非常简单,只需要参考如下两种示例配置即可:
<!--方式一:嵌套查询-->
<collection property="ordersList" column="id"
ofType="com.itheima.po.IdCard"
select="com.itheima.mapper.OrdersMapper.selectOrders" />
<!--方式一:嵌套结果-->
<collection property="ordersList" ofType="com.itheima.po.Orders">
<id property="id" column="orders_id" />
<result property="number" column="number" />
</collection>
9.4多对多
多对多的关联关系也是非常常见的。以订单和商品为例,一个订单可以包含多种商品,而一种商品又可以属于多个订单,订单和商品就属于多对多的关系
在数据库中,多对多的关联关系通常使用一个中间表来维护,中间表中的订单id作为外键参照订单表的id,商品id作为外键参照商品表的id