Day15. 高级查询 一对多映射关系 -MyBatis高级

1.collection集合的嵌套结果映射

1.1 基本使用

association类似,集合的嵌套结果映射就是通过一次SQL查询将所有的结果查询出来,然后通过配置的结果映射,将数据映射到不同的对象中去。

准备数据

一个用户有多个角色,一个角色又有多种权限

//用户实体类
public class User {
    private Integer id;
    private String username;
    private String password;
    //一对多:一个用户对应多种角色
    private List<Role> role;
}
//角色类
public class Role {
    private Integer id;
    private String role;
    private Date createDate;
}

如何查询出全部用户及其角色

UserMapper.xml

    <resultMap id="userRoleListMap" type="com.example.pojo.User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <collection property="roleList" columnPrefix="role_"
                    javaType="com.example.pojo.Role">
            <id property="id" column="id"/>
            <result property="role" column="role"/>
            <result property="createDate" column="create_date"/>
        </collection>
    </resultMap>

👇

    <resultMap id="userRoleListMap" type="com.example.pojo.User" extends="userMap">
        <collection property="roleList" columnPrefix="role_"
                    ofType="com.example.pojo.Role">
            <id property="id" column="id"/>
            <result property="role" column="role"/>
            <result property="createDate" column="create_date"/>
        </collection>
    </resultMap>

👇

    <resultMap id="userRoleListMap" type="com.example.pojo.User" extends="userMap">
        <collection property="roleList" columnPrefix="role_"
                    ofType="com.example.pojo.Role" resultMap="com.example.mapper.RoleMapper.roleMapper"/>
    </resultMap>

select

    <select id="selectAllUserAndRoles" resultMap="userRoleListMap">
        select user.id, username, password, r.id "role_id", r.role "role_role", r.create_date "role_create_date"
        from user
                 inner join user_role_merage urm on user.id = urm.user_id
                 inner join role r on urm.role_id = r.id
    </select>

测试成功
在这里插入图片描述

踩坑

在这里插入图片描述
在这里插入图片描述

1.2 一对多中MyBatis的处理规则

MyBatis在处理结果的时候,会判断结果是否相同,如果是相同的结果,则只会保留第一个结果,所以这个问题的关键点是MyBatis如何判断结果是否相同。
最简单的情况是在映射配置中有一个id标签,例如:

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

我们对id的理解是:它配置的字段为表的主键(联合主键时可以配置多个id标签)。id的唯一作用就是在嵌套的配置映射中判断数据是否相同。
在这里插入图片描述
在这里插入图片描述

由此一来,上面的查询就不难理解了,因为其id相同,所以它们属于同一个用户

在RBAC中,除了一个用户对应多个角色外,每一个角色还会对应多种权限,所以在现有的例子的基础上再加一级,获取角色对应的所有权限。

@Data
public class Privilege {
    private Integer id;

    private String name;

    private String url;
}

UserMapper.xml

 <resultMap id="userRoleListMap" type="com.example.pojo.User" extends="userMap">
        <collection property="roleList" columnPrefix="role_"
                    ofType="com.example.pojo.Role"
                    resultMap="com.example.mapper.RoleMapper.rolePrivilegeListMap"/>
    </resultMap>


 <select id="selectAllUserAndRoles" resultMap="userRoleListMap">
        select user.id,
               username,
               password,
               r.id           "role_id",
               r.role         "role_role",
               r.create_date  "role_create_date",
               privilege.id   "role_privilege_id",
               privilege.name "role_privilege_name",
               privilege.url  "role_privilege_url"
        from user
                 inner join user_role_merage urm on user.id = urm.user_id
                 inner join role r on urm.role_id = r.id
                 left join role_privilege_merage rpm on r.id = rpm.role_id
                 left join privilege on privilege.id = rpm.pri_id;
    </select>

RoleMapper.xml

    <resultMap id="roleMapper" type="com.example.pojo.Role">
        <id property="id" column="id"/>
        <result property="role" column="role"/>
        <result property="createDate" column="create_date"/>
    </resultMap>
   
    <resultMap id="rolePrivilegeListMap" type="com.example.pojo.Role"
               extends="roleMapper">
        <collection property="privilegeList" ofType="com.example.pojo.Privilege"
                    columnPrefix="privilege_"
                    resultMap="com.example.mapper.PrivilegeMapper.BaseResultMap"/>
    </resultMap>

PrivilegeMapper.xml

  <resultMap id="BaseResultMap" type="com.example.pojo.Privilege">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="url" jdbcType="VARCHAR" property="url" />
  </resultMap>

测试成功
在这里插入图片描述

注意:因为privilege嵌套在rolePrivilegeListMap,而rolePrivilegeListMap的前缀是“role_”,所以BaseResultMap中的前缀就变成了“role_privilege_”。前缀一定不要写错。

2.collection集合的嵌套查询

使用嵌套查询来完成嵌套结果映射的功能。

PrivilegeMapper.xml

    <select id="selectPrivilegeByRoleId" resultMap="BaseResultMap">
        select privilege.*
        from privilege
                 inner join role_privilege_merage on privilege.id = role_privilege_merage.pri_id
        where role_id = #{roleId};
    </select>

RoleMapper.xml

    <resultMap id="rolePrivilegeListMapSelect" type="com.example.pojo.Role" extends="roleMapper">
        <collection property="privilegeList" select="com.example.mapper.PrivilegeMapper.selectPrivilegeByRoleId"
                    column="{roleId=id}"/>
    </resultMap>

    <select id="selectRoleByUserId" resultMap="rolePrivilegeListMapSelect">
        select role.*
        from role
                 inner join user_role_merage urm on role.id = urm.role_id
        where user_id = #{userId};
    </select>

UserMapper.xml

    <resultMap id="userRoleListMap" type="com.example.pojo.User" extends="userMap">
        <collection property="roleList" select="com.example.mapper.RoleMapper.selectRoleByUserId"
                    column="{userId=id}"/>
    </resultMap>

    <select id="selectAllUserAndRolesSlect" resultMap="userRoleListMap">
        select *
        from user
        where user.id = #{id};
    </select>

测试成功
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值