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

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:一对多关联时使用,封装为一个对象集合
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值