Mybatis中的关系映射(一对一,一对多,多对多)

转载:https://www.cnblogs.com/black-spike/p/7772458.html

在网上寻了很久,大多数讲关系性的文章都是大篇幅的去将表照搬上来,本来就很生硬,此文就不在讲述关系性映射的具体实现,转而从浅层来讲讲其概念性.

1.1 关联关系概述

在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多,如下图所示:


三种关系如下:

  • 一对一:在任意一方引入对方主键作为外键。

  • 一对多:在“多”的一方,添加“一”的一方的主键作为外键。

  • 多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键。

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

  • 一对一的关系:就是在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a。

  • 一对多的关系:就是一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a。

  • 多对多的关系:在A类中定义B类类型的集合,在B类中定义A类类型的集合。

1.2 一对一

在现实生活中,一对一关联关系是十分常见的。例如,一个人只能有一个身份证,同时一个身份证也只会对应一个人

<resultMap>元素中,包含了一个<association>子元素,MyBatis就是通过该元素来处理一对一关联关系的。
在<association>元素中,通常可以配置以下属性:

  • property:指定映射到的实体类对象属性,与表字段一一对应;

  • column:指定表中对应的字段;

  • javaType:指定映射到实体对象属性的类型;

  • select:指定引入嵌套查询的子SQL语句,该属性用于关联映射中的嵌套查询;

  • fetchType:指定在关联查询时是否启用延迟加载。该属性有lazy和eager两个属性值,默认值为lazy(即默认关联映射延迟加载)。

MyBatis加载关联关系对象主要通过两种方式:嵌套查询和嵌套结果。

  • 嵌套查询:嵌套查询是通过执行另外一条SQL映射语句来返回预期的复杂类型。

      嵌套查询是在查询SQL中嵌入一个子查询SQL;
    
      嵌套查询会执行多条SQL语句;
    
      嵌套查询SQL语句编写较为简单;
  • 嵌套结果:嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。

      嵌套结果是一个嵌套的多表查询SQL;
    
      嵌套结果只会执行一条复杂的SQL语句;
    
      嵌套结果SQL语句编写比较复杂;

虽然使用嵌套查询的方式比较简单,但是嵌套查询的方式要执行多条SQL语句,这对于大型数据集合和列表展示不是很好,
因为这样可能会导致成百上千条关联的SQL语句被执行,从而极大的消耗数据库性能并且会降低查询效率。

使用<association>元素进行一对一关联映射非常简单,只需要参考如下两种示例配置即可。

  • 嵌套查询,property指的是类属性,column指的是表字段,select表示嵌套的子查询,javaType表示关联属性类型。
<association property="card" column="card_id" 
     javaType="com.itheima.po.IdCard" select="com.itheima.mapper.IdCardMapper.findCodeById" />
  • 嵌套结果,property指的是类属性,column指的是表字段,javaType表示关联属性类型。
<association property="card" javaType="com.itheima.po.IdCard">
              <id property="id" column="card_id" />
              <result property="code" column="code" />
    </association>

1.3 一对多

开发人员接触更多的关联关系是一对多(或多对一)。例如,一个用户可以有多个订单,同时多个订单归一个用户所有。

<resultMap>元素中,包含了一个<collection>子元素,MyBatis就是通过该元素来处理一对多关联关系的。
<collection>子元素的属性大部分与<association>元素相同,但其还包含一个特殊属性--ofType 。

  • ofType:ofType属性与javaType属性对应,它用于指定实体对象中集合类属性所包含的元素类型。

<collection>元素的使用也非常简单,同样可以参考如下两种示例进行配置,具体代码如下:

  • 嵌套查询,property指的是类属性,column指的是表字段,select表示嵌套的子查询,ofType表示关联的集合类属性类型。
<collection property="ordersList" column="id" ofType="com.itheima.po.Orders"
 select=" com.itheima.mapper.OrdersMapper.selectOrders" />
  • 嵌套结果,property指的是类属性,column指的是表字段,ofType表示关联的集合类属性类型。
<collection property="ordersList" ofType="com.itheima.po.Orders">
            <id property="id" column="orders_id" />
            <result property="number" column="number" />
  </collection> 

1.3 多对多

在实际项目开发中,多对多的关联关系也是非常常见的。以订单和商品为例,一个订单可以包含多种商品,而一种商品又可以属于多个订单

在数据库中,多对多的关联关系通常使用一个中间表来维护,中间表中的订单id作为外键参照订单表的id,商品id作为外键参照商品表的id。

上述这种是多对多映射,横跨了三张表,两张一对多关系型表.

   <id column="id" property="id"></id>
   <!--一对一-->
   <association property="user" javaType="User" autoMapping="true">
      <id column="uid" property="id"></id>
   </association>
   <!--一对多-->
   <collection property="orderdetails" javaType="List" ofType="Orderdetail" autoMapping="true">
      <id column="detail_id" property="id"></id>
      <!--订单详情和商品的一对一的关系-->
      <association property="item" javaType="Item" autoMapping="true">
         <id column="iid" property="id"></id>
      </association>
   </collection>

</resultMap>

<!--多对多查询-->
<select id="queryOrderAndUserAndOrderdetailAndItemByOrderNumber" resultMap="orderAndUserAndOrderdetailsAndItemResultMap">
   SELECT
      *,u.id as uid,od.id as detail_id,i.id as iid
   FROM
      tb_order o
   INNER JOIN tb_user u ON o.user_id = u.id
   INNER JOIN tb_orderdetail od on od.order_id = o.id
   INNER JOIN tb_item i on i.id = od.item_id
   WHERE
      o.order_number = #{orderNumber}
</select>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值