MyBatis的关联映射看这一篇就行了


什么是关联关系?

在关系型数据中,多表之间存在三种关联关系,分别是一对一、一对多、多对多,通过下图更直观地了解一下:
在这里插入图片描述
接下来对着三种关联关系进行说明:
一对一:在任意一方引入对方主键作为外键
一对多:在 “多” 的一方,添加 “一” 的一方的主键作为外键
多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键

在Java中,通过对象也可以进行关系描述,如下代码所示:

一对一

class A {
	B b;
}

Class B {
	A a;
}

一对多

class A {
	List<B> b;
}

class B {
	A a;
}

多对多

class A {
	List<B> b;
}

class B {
	List<A> a;
}

一对一

在现实生活中,一对一关联十分常见。例如,一个人只能有一张身份证,同时一张身份证也只会对应一个人。
在这里插入图片描述
在MyBatis中通过<resultMap>中的子元素<association>来处理一对一关联映射。

<association>元素中,通常配置以下属性:

  • property:指定映射到的实体类对象属性,与表字段一一对应
  • column:指定表中对应的字段
  • javaType:指定映射到实体对象属性的类型
  • select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询
  • fetchType:指定在关联查询时是否启用延迟加载。fetchType属性有lazy和eager两个属性值,默认是lazy(即默认关联映射延迟加载)

<association>元素有两种配置方式:

  1. 嵌套查询
<association property="card" colume="card_id" javaType="com.lwz.po.IdCard"
			select="com.lwz.mapper.IdCardMapper.findCodeById" />
  1. 嵌套结果
<association property="card" javaType="com.lwz.po.IdCard">
	<id property="id" column="card_id" />
	<result property="code" column="code" />
</association>

因为嵌套查询很可能会导致成百上千条关联的SQL语句被执行,从而极大消耗数据库性能并且会降低查询效率。为此,尽可能的使用嵌套结果来进行关联查询。

接下来通过实例来了解<association>元素的使用。现在有两张表,一张是person,另一张是idCard,idCard中的每一个id都对应着一个人,person中的每一个card_id对应着一张身份证。现在需要通过输入person的id属性来查询person信息以及其idCard信息。

表对应的实体类中的属性如下图:
在这里插入图片描述
表中的字段以及记录如下图:
在这里插入图片描述
映射文件代码如下:

<!-- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 -->
<select id="findPersonById2" parameterType="Integer" 
                                   resultMap="IdCardWithPersonResult2">
    SELECT p.*,idcard.code
    from tb_person p,tb_idcard idcard
    where p.card_id=idcard.id 
    and p.id= #{id}
</select>
<resultMap type="Person" id="IdCardWithPersonResult2">
    <id property="id" column="id" />
    <result property="name" column="name" />
    <result property="age" column="age" />
    <result property="sex" column="sex" />
    <!-- association中的property是当Person的属性名,javaType是要映射在property中的属性类型 -->
    <association property="card" javaType="IdCard">
    	<!-- 下面的元素均为JavaType中的属性以及对应的列名 -->
        <id property="id" column="id" />
        <result property="code" column="code" />
    </association>
</resultMap>

一对多

与一对一关联关系相比,开发人员接触更多的关联关系是一对多(或多对一)。例如一个用户可以有多个订单,同时多个订单归于一个用户。
在这里插入图片描述
在MyBatis中使用<resultMap>元素的子元素<collection>元素来处理一对多关联关系。<collection>元素和<association>元素大致相同,不过<collection>元素还包含一个特殊的属性——ofType。ofType属性和javaType属性对应,用于指定实体类对象中集合类属性所包含的元素类型。

<collection>元素也有两种配置方式,这里就使用效率更高的嵌套结果作为示例。现在有两张表,一张是用户表,另一张使订单表,一个用户可以对应多个订单现在需要通过用户的id属性来查询用户信息以及其所有订单信息。

表中的字段以及记录如下图:
在这里插入图片描述
表对应的实体类中的属性如下图:
在这里插入图片描述
映射文件代码如下:

<!-- 一对多:查看某一用户及其关联的订单信息 
	      注意:当关联查询出的列名相同,则需要使用别名区分 -->
<select id="findUserWithOrders" parameterType="Integer" 
					   resultMap="UserWithOrdersResult">
	SELECT u.*,o.id as orders_id,o.number 
	from tb_user u,tb_orders o 
	WHERE u.id=o.user_id 
       and u.id=#{id}
</select>
<!-- type是需要映射的普通Java类  -->
<resultMap type="User" id="UserWithOrdersResult">
	<id property="id" column="id"/>
	<result property="username" column="username"/>
	<result property="address" column="address"/>
	<!-- 一对多关联映射:collection 
		ofType表示属性集合中元素的类型,List<Orders>属性即Orders类 -->
	<collection property="ordersList" ofType="Orders">
		<id property="id" column="orders_id"/>
		<result property="number" column="number"/>
	</collection>
</resultMap>

多对多

在实际开发中,多对多的关联关系也是非常常见的。以订单和商品为例,一个订单可以包含多种商品,而一种商品又可以属于多个订单,订单和商品就属于多对多的关联关系。
在这里插入图片描述
在数据库中,多对多的关联关系通常使用一个中间表来进行维护,中间表的订单id作为外键参照订单表的id,商品id作为外键参照商品表的id。现在有三张表,订单表、中间表、商品表,现在需要通过订单的id属性来通过中间表查询所有商品信息。
在这里插入图片描述
表中的字段以及记录如下图:
在这里插入图片描述
表对应的实体类中的属性如下图:
在这里插入图片描述
映射文件代码如下:

<!-- 多对多嵌套结果查询:查询某订单及其关联的商品详情 -->
<select id="findOrdersWithPorduct2" parameterType="Integer" 
         resultMap="OrdersWithPorductResult2">
    select o.*,p.id as pid,p.name,p.price
    from tb_orders o,tb_product p,tb_ordersitem oi
    WHERE oi.orders_id=o.id 
    and oi.product_id=p.id 
    and o.id=#{id}
</select>
<!-- 自定义手动映射类型 -->
<resultMap type="Orders" id="OrdersWithPorductResult2">
    <id property="id" column="id" />
    <result property="number" column="number" />
    <!-- 多对多关联映射:collection -->
    <collection property="productList" ofType="Product">
        <id property="id" column="pid" />
        <result property="name" column="name" />
        <result property="price" column="price" />
    </collection>
</resultMap>

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lw中

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值