MyBatis 一对一,一对多,多对多

2023-05-16

MyBatis 一对一,一对多,多对多

阅读目录

  • 什么是一对一,一对多,多对多?
  • 数据库和实体(POJO)的设定
  • 一对一
  • 一对多
  • 多对多
  • 总结

回到顶部

什么是一对一,一对多,多对多?

以用户和订单举例,

一对一 : 一个订单只属于一个用户 ==> 订单对用户是一对一关系

      一个用户只能有一个订单 ==> 用户对订单是一对一关系

一对多 : 一个用户可以拥有多个订单 ==> 用户对订单是一对多关系

多对多 : 一个订单可以有多种商品,并且一种商品可以被多个订单包含 ==> 商品和订单是多对多关系

回到顶部

数据库和实体(POJO)的设定

user表

oders表

User类(省略geter&seter)

Oders类(省略geter&seter)

下面用实例讲解一对一和一对多,只展示Mapper映射文件内容,Dao,Service,Controller层内容省略

回到顶部

一对一

一个订单对应一个用户,即一对一(订单对用户是一对一)

在POJO上的实现是,Orders类内包含一个User属性

现在我们用订单id来查询订单和对应用户的数据(关联查询)

如果用resultType的写法,myBatis就不能将查询结果绑定到Orders的user对象内,如下图,

运行后oders对象内的user属性将为null,Oders类内定义的其他属性可以正常赋值

 为了解决这个问题,我们可以用resultMap来替代resultType

有两种实现方法,一种是嵌套结果,一种是嵌套查询

一.嵌套结果

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<select id="getOrderAndUserByOrderId" resultMap="ordersAndUser">

    SELECT * FROM orders o, user u WHERE o.user_id=u.id AND o.id=#{id}

</select>

<!-- 这是resultMap -->

<resultMap type="com.jy.entity.Orders" id="ordersAndUser">

    <id property="id" column="id"/>

    <result property="user_id" column="user_id"/>

    <!-- 这是映射 -->

    <association property="user" javaType="com.jy.entity.User">

        <id property="id" column="id" />

        <result property="username" column="username"/>

        <result property="password" column="password"/>

        <result property="realname" column="realname"/>

    </association>

</resultMap>

  <resultMap> :

    type ==> Orders类的路径

    id ==> resultMap名

  <association> :

    property ==> Orders类内user属性名

    jayaType ==> user的类路径

二.嵌套查询

1

2

3

4

5

6

7

8

9

10

11

12

13

<select id="getOrderAndUserByOrderId" resultMap="ordersAndUser">

    SELECT * FROM orders where id=#{id}

</select>

<resultMap type="com.jy.entity.Orders" id="ordersAndUser">

    <id property="id" column="id"/>

    <result property="user_id" column="user_id"/>

    <!-- column是传的参数, select是调用的查询 -->

    <association property="user" column="user_id" select="getUserById"/>

</resultMap>

 

<select id="getUserById" resultType="user">

    SELECT * FROM user WHERE id=#{user_id}

</select>

  <association> :

    property ==> Oders类内的user属性

    column ==> 调用查询时传入的参数

    select ==> 调用的查询语句

通过以上的嵌套结果或嵌套查询的方法,即可成功为Oders内的user属性赋值!

回到顶部

一对多

 一个用户有多个订单,即一对多(用户对订单是一对多)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<select id="getUserAndOrdersByUserId" resultMap="UserAndOrders">

    SELECT u.id uid, u.username, u.password, u.realname, o.id, o.user_id

    FROM user u, orders o

    WHERE u.id=o.user_id AND u.id=#{id}

</select>

 

<resultMap type="com.jy.entity.User" id="UserAndOrders">

    <id property="id" column="uid"/>

    <result property="username" column="username"/>

    <result property="password" column="password"/>

    <result property="realname" column="realname"/>

    <collection property="orders" ofType="com.jy.entity.Orders">

        <id property="id" column="id"/>

        <result property="user_id" column="user_id"/>

    </collection>

</resultMap>

  <collection> :

    property ==> User类中的orders属性

    ofType ==> Orders类路径

注意!

订单只能查询到一条结果??

用户和订单的id值如果名字一样的话,会发生冲突!这样查询结果中只会有一个订单,查不到所有订单!

解决办法 : 在SQL文中给其中一个id起别名,然后在column属性中输入别名!!

回到顶部

多对多

使用中间表来操作,省略

回到顶部

总结

1.不管是一对一还是多对多,都要使用<resultMap> ,属性有id 和type

2.一对一中,<resultMap>内要用<association>来映射复杂对象,属性有 :

  (property和javaType) ==> 嵌套结果

  (property, column, select) ==> 嵌套查询

3.一对多中,<resultMap>内要用<collection>来映射复杂对象,属性有property和ofType

4.注意防范<resultMap>和<association>或<collection>中字段名冲突的问题!

 

转自 https://www.cnblogs.com/jinyu59/p/10833406.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatis 一对一,一对多,多对多 的相关文章

随机推荐