欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MyBatis 多表关联查询(手动映射)

程序员文章站 2022-04-22 09:47:43
MyBatis多表关联查询如果使用多表查询,那么表之间一定有这三种关系:一对一,比如一个人有且只有一个身份证号一对多,比如一个人可以有多个银行卡多对多,比如一个学生可以选择多个课程,一个课程也可以被多个学生选择使用MyBatis实现多表查询,根据表与表之间的关系不同,具体实现就会有些不同首先分析问题:当我们进行多表查询时,返回的结果集一定是两个表中的数据,那么我们总不能再准备一个(包含两个表中所有字段的)POJO来映射这次返回的结果。这时,我们可以考虑让第一个表的POJO包含第二个表的...

MyBatis多表关联查询

如果使用多表查询,那么表之间一定有这三种关系:

  • 一对一,比如一个人有且只有一个身份证号
  • 一对多,比如一个人可以有多个银行卡
  • 多对多,比如一个学生可以选择多个课程,一个课程也可以被多个学生选择

使用MyBatis实现多表查询,根据表与表之间的关系不同,具体实现就会有些不同

首先分析问题:

  • 当我们进行多表查询时,返回的结果集一定是两个表中的数据,那么我们总不能再准备一个(包含两个表中所有字段的)POJO来映射这次返回的结果。
  • 这时,我们可以考虑让第一个表的POJO包含第二个表的POJO(其实就是:为第一个表的POJO增加一个属性,类型就为第二个表的POJO);然后通过MyBatis提供的手动映射的方式,将结果集 分别 封装到对应的对象中去

一对一关系查询

使用resultMap标签手动映射时,它里面还有一个association子标签,

association:联合标签

  • property属性:值为第一表中添加的POJO属性名
  • JavaType属性:值为对应的POJO的类型

案例:查询出订单的信息,并且包含该订单的用户信息

public class OrderVo {
    private Integer id;
    private Integer uid;
    private String number;
    private Timestamp createtime;
    private String des;
    private User user;//订单中的用户信息可以放在这个user属性中
}
    <!-- 查询出来的字段有:订单id,该订单的用户id,订单编号,订单创建时间,订单简介,对应用户的id,用户名-->
	<select id="findOrderUserList" resultMap="resultMap_order_user">
        SELECT o.id,o.uid,o.number,o.createtime,o.des,u.id,u.username 
        FROM t_orders o JOIN t_user u ON o.uid=u.id
	</select>
    <resultMap id="resultMap_order_user" type="ordervo">
        <id column="id" property="id"/>
        <result column="uid" property="uid"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <association property="user" javaType="User">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
        </association>
    </resultMap>

使用association标签,将属于用户的字段放入order对象的user属性中

一对多关系查询

一对多的关系,只需要给第一个表中对应的POJO准备一个放多个第二个表中POJO对象的列表即可

这样第一个表中对应第二个表中的多条数据就可以存放在这个list中

这时就不能使用association标签了,resultMap标签中还有另一个collection子标签

collection:

  • property属性:值为POJO中的属性名
  • ofType属性:值为该集合的泛型类型

案例:查询出所有用户,并且包含每个用户的所有订单信息

public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;
    private String remark;
    private List<OrderVo> orderList;
}
    <!-- 查询出来的字段有:用户的id,用户名,密码,邮箱,说明,用户的订单id,订单对应的用户id,订单的简介-->
    <select id="findUserOrder" resultMap="result_user_orders">
        SELECT u.id as uid,u.username,u.password,u.email,u.remark,o.id,o.uid,o.des 
        FROM t_user u INNER JOIN t_orders o ON u.id=o.uid
    </select>
    <resultMap id="result_user_orders" type="User">
        <id column="uid" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="email" property="email"/>
        <result column="remark" property="remark"/>
        <collection property="orderList" ofType="OrderVo">
            <id property="id" column="id"/>
            <result property="uid" column="uid"/>
            <result property="des" column="des"/>
        </collection>
    </resultMap>

collection标签可以将属于订单的字段放到一个OrderVo对象中,再将该用户的所有Order放到user的orderList属性中

多对多关系查询

要实现多对多的关系,那么一定会有一个第三张表作为关系表

我们要把多对多的关系理解为一个双向的一对多:表一中的一条数据对应关系表中的多条记录,表二中的一条数据也对应关系表中的多条记录

两个POJO中分别包含对方对象List的引用

案例:查询每一个角色分别对应哪些用户
(一个用户可以有多个角色,一个角色中可以有多个用户)

public class Role {
    private Integer id;
    private String name;
    private String keyword;
    private List<User> userList;
}
    <!-- 查询出来的字段有:角色的id,角色名,角色描述,对应用户的id,用户名,密码,邮箱-->
    <select id="findRoleUserList" resultMap="result_role_users">
        SELECT r.id as rid,r.name,r.keyword,u.id as uid,u.username,u.password,u.email
        FROM t_role r LEFT JOIN t_role_user ru ON r.id=ru.role_id 
        LEFT JOIN t_user u ON ru.user_id=u.id
    </select>
    <resultMap id="result_role_users" type="role">
        <id column="rid" property="id"/>
        <result column="name" property="name"/>
        <result column="keyword" property="keyword"/>
        <collection property="userList" ofType="User">
            <id column="id" property="uid"/>
            <result column="username" property="username"/>
            <result column="password" property="password"/>
            <result column="email" property="email"/>
        </collection>
    </resultMap>

既然是对多的关系,那么同样,也可以:

查询每一个用户都有哪些角色信息

public class User {
    private Integer id;
    private String username;
    private String password;
    private String email;
    private String remark;
    private List<Role> roleList;
}
    <!-- 查询出来的字段有:用户的id,用户名,密码,邮箱,说明,对应角色的id,角色名,角色简介-->
	<select id="findUserRoleList" resultMap="result_user_roles">
        SELECT u.id as uid,u.username,u.password,u.email,u.remark,r.id as rid,r.name,r.keyword
        WHERE t_user u LEFT JOIN t_role_user ru ON u.id=ru.user_id
        LEFT JOIN t_role r ON ru.role_id=r.id
    </select>
    <resultMap id="result_user_roles" type="user">
        <id column="uid" property="id"/>
        <result column="username" property="username"/>
        <result column="password" property="password"/>
        <result column="email" property="email"/>
        <result column="remark" property="remark"/>
        <collection property="roleList" ofType="role">
            <id column="rid" property="id"/>
            <result column="name" property="name"/>
            <result column="keyword" property="keyword"/>
        </collection>
    </resultMap>

总结:

  • association:一对一关联时使用,封装为一个对象属性
  • collection:一对多关联时使用,封装为一个对象集合

本文地址:https://blog.csdn.net/zxy144/article/details/109481256