Mybatis入门系列之(十二)——一对多查询

一对多查询

第一种解决方案

这里假定一个用户对应多个角色,在SysUser.java中添加如下字段:

/**
 * 一个用户对应多个角色
 */
private List<SysRole> roleList;

public List<SysRole> getRoleList() {
    return roleList;
}

public void setRoleList(List<SysRole> roleList) {
    this.roleList = roleList;
}

在UserMapper.xml中添加resultMap,代码如下:

<resultMap id="userRoleListMap" type="tk.mybatis.simple.model.SysUser">
    <id property="id" column="id"/>
    <result property="userName" column="user_name"/>
    <result property="userPassword" column="user_password"/>
    <result property="userEmail" column="user_email"/>
    <result property="headImg" column="head_img" jdbcType="BLOB"/>
    <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>

    <collection property="roleList" columnPrefix="role_"
                javaType="tk.mybatis.simple.model.SysRole">
        <result property="id" column="id"/>
        <result property="roleName" column="role_name"/>
        <result property="enabled" column="enabled"/>
        <result property="createBy" column="create_by"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
    </collection>
</resultMap>

和一对一关系做比较,将association修改为了collection,property设置为了roleList之外,其他的配置基本一样。有了一对一关系的基础,我们这里对userRoleListMap进行大刀阔斧的改进,改进后的代码如下:

<resultMap id="userRoleListMap" extends="userMap"
           type="tk.mybatis.simple.model.SysUser">
    <collection property="roleList" columnPrefix="role_"
                resultMap="tk.mybatis.simple.mapper.RoleMapper.roleMap"/>  
</resultMap>

增加查询的语句如下:

<select id="selectAllUserAndRoles" resultMap="userRoleListMap">
    SELECT
      u.id,
      u.user_name,
      u.user_password,
      u.user_info,
      u.user_email,
      u.head_img,
      u.create_time,
      r.id "role_id",
      r.role_name "role_role_name",
      r.enabled "role_enabled",
      r.create_by "role_create_by",
      r.create_time "role_create_time"
    FROM  sys_user u
    INNER JOIN sys_user_role ur on u.id = ur.user_id
    INNER JOIN sys_role r ON r.id  = ur.role_id
</select>

在UserMapper.java接口中增加如下方法:

/**
 * 获取所有的用户以及对应的所有角色
 * @return
 */
List<SysUser> selectAllUserAndRoles();

测试代码如下:

@Test
public void testSelectAllUserAndRoles(){
    SqlSession sqlSession = getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<SysUser> userList = userMapper.selectAllUserAndRoles();
        System.out.println("用户数量:"+userList.size());
        userList.forEach((user)->{
            System.out.println("用户名:"+user.getUserName());
            List<SysRole> roleList = user.getRoleList();
            roleList.forEach((role)->{
                System.out.println("角色名:"+role.getRoleName());
            });
        });
    }finally {
        sqlSession.close();
    }
}

输出结果如下:

[DEBUG] 2018-04-29 22:34:10,731 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT u.id, u.user_name, u.user_password, u.user_info, u.user_email, u.head_img, u.create_time, r.id "role_id", r.role_name "role_role_name", r.enabled "role_enabled", r.create_by "role_create_by", r.create_time "role_create_time" FROM sys_user u INNER JOIN sys_user_role ur on u.id = ur.user_id INNER JOIN sys_role r ON r.id = ur.role_id 
[DEBUG] 2018-04-29 22:34:10,750 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 
[TRACE] 2018-04-29 22:34:10,853 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, user_name, user_password, user_info, user_email, head_img, create_time, role_id, role_role_name, role_enabled, role_create_by, role_create_time
[TRACE] 2018-04-29 22:34:10,853 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, admin, 123456, <<BLOB>>, admin@mybatis.tk, <<BLOB>>, 2018-04-24 17:08:34.0, 1, 管理员, 1, 1, 2018-04-24 14:34:34.0
[TRACE] 2018-04-29 22:34:10,869 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, admin, 123456, <<BLOB>>, admin@mybatis.tk, <<BLOB>>, 2018-04-24 17:08:34.0, 2, 普通用户, 1, 1, 2018-04-24 15:08:34.0
[TRACE] 2018-04-29 22:34:10,869 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1001, test, 123456, <<BLOB>>, test@mybatis.tk, <<BLOB>>, 2018-04-24 17:08:34.0, 2, 普通用户, 1, 1, 2018-04-24 15:08:34.0
[DEBUG] 2018-04-29 22:34:10,869 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 3
用户数量:2
用户名:admin
角色名:管理员
角色名:普通用户
用户名:test
角色名:普通用户
以下的内容很重要:

通过日志可以清楚地看到, SQL 执行的结果数有 3 条,后面输出的用户数是 2 ,也就是说
本来查询出的 3 条结果经过 MyBatis 对 collection 数据的处理后,变成了两条 。

我们都知道,因为第一个用户拥有两个角色,所以转换为一对多的数据结构后就变成了两
条结果。那么, MyBatis 又是怎么知道要处理成这样的结果呢?

理解 MyBatis 处理的规则对使用一对多配置是非常重要的,如果只是一知半解,很容易就
会遇到各种莫名其妙的问题,所以针对 MyBatis 处理中的要点,下面进行一个详细的阐述。

先来看 MyBatis 是如何知道要合并 ad.min 的两条数据的,为什么不把 test 这条数据也合
井进去呢?
MyBatis 在处理结果的时候 , 会判断结果是否相同 ,如果是相 同的结果 ,则 只会保留第一
个结果,所以这个问题的关键点就是 MyBatis 如何判断结果是否相同。 MyBatis 判断结果是否
相同时,最简单的情况就是在映射配置中至少有一个 id 标签 , 在 userMap 中配置如下。

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

我们对 id (构造方法中为 idArg )的理解一般是,它配置的字段为表的主键(联合主键时可以配置多个 id 标签),因为 MyBatis 的 resultMap 只用于配置结果如何映射 , 并不知道这个表具体如何。 id 的唯一作用就是在嵌套的映射配置时判断数据是否相同,当配置id标签时, MyBatis 只需要逐条比较所有数据中 id 标签配置的字段值是否相同 即可。在配置嵌套结果查询时 ,配置 id 标签可以提高处理效率。

这样一来 ,上面的查询就不难理解了,因为前两条数据 的 userMap 部分的 i d 相同,所以它们属于同一个用户,因此这条数据会合并到同一个用户中。为了让大家更清楚地理解 id 的作用,可以临时对 userMap 的 映射进行如下修改(将userPassword作为id)。

 <resultMap id="userMap" type="tk.mybatis.simple.model.SysUser" autoMapping="false">
        <id  property="userPassword" column="user_password"/>
        <result property="id" column="id"/>
        <result property="userName" column="user_name"/>
        <!--<result property="userPassword" column="user_password"/>-->
        <result property="userEmail" column="user_email"/>
        <result property="headImg" column="head_img" jdbcType="BLOB"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>

条数据就会合并为 l 条数据。对 userMap 做好临时修改后,在测试数据中,用户的密码都是 123456 ,因此如果用密码作为 id , 按照上面的说法,这 3条数据就会合并为 l 条数据。对 userMap 做好临时修改后再次测试,结果如下:

用户数量:1
用户名:admin
角色名:管理员
角色名:普通用户

是不是变成了 一个用户?用户信息保留的是第一条数据的信息 , 因此用户名是 admin 。 角色为什么不是 3 条呢?因为“普通用户 ” 这个角色重复了 , 所以也只保留了第一个出现的“普通用户”,具体的合并规则后面会详细说明。

大家通过这个简单的例子应该明白 id 的作用了 。需要注意 , 很可能会出现一种没有配置id 的情况。 没有配置 id 时, MyB ati s 就会把 resultMap 中配置的所有字段进行比较,如果所有字段的值都相同就合并,只要有一个字段值不同,就不合井。

提示:
在嵌套结果配直 id 属性时 如果查询语句中没有查询 id 属性配直的列,就会导致 id对应的值为 null 。 这种情况下,所有值的 id 都相同,因此会使嵌套的集合中只有一条数据。所以在配直 id 列时,查询语句中必 须包含该列 。

可以对 userMap 再次修改 , 将 id 标签改为 result ,然后执行测试查看结果 。这时的结
果和使用 id 标签配置 id 属性时的结果相同 , 因为 admin 用户在 userMap 这部分配置的属性
都相同,因此也会合井 。虽然结果相同,但是由于 MyBatis 要对所有宇段进行比较 ,因此当字
段数为 M 时 ,如果查询结果有 N 条,就需要进行 M × N 次比较 , 相比配置id 时的 N 次比较,
效率相差更多,所以要尽可能配置 id 标签。

前面将 id 标签配置为 userPassword 时,最后的结果少了 一个角色,这是因为 MyBatis 会对嵌套查询的每一级对象都进行属性 比较。 MyB atis 会首先比较顶层 的对象,如果 S ysUser部分相同,就继续比较 SysRole 部分 , 如果 SysRole 不同,就会增加一个 Sys Role ,两个SysRole 相同就保留前一个。假设

SysRole 还有下一级,仍然按照该规则去比较。

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

如果在 PrivilegeMap p er.xm l 中没有 privilegeMap 映射配置,代码如下:

<mapper namespace="tk.mybatis.simple.mapper.PrivilegeMapper">
    <resultMap id= "privilegeMap" type= "tk.mybatis.simple.model.SysPrivilege">
        <id  property="id" column = "id"/>
        <result  property= "privilegeName" column = "privilege_name"/>
        <result  property= "privilegeUrl" column = "privilege_url"/>
    </resultMap>
</mapper>

然后在 SysRole 类中添加如下属性和方法 。

/**
 * 一个角色对应多个权限
 */
List<SysPrivilege> privilegeList;

public List<SysPrivilege> getPrivilegeList() {
    return privilegeList;
}

public void setPrivilegeList(List<SysPrivilege> privilegeList) {
    this.privilegeList = privilegeList;
}

在 RoleMapper.xml 文件中,增加如下 resultMap 配置,代码如下:

<resultMap id="rolePrivilegeListMap" extends="roleMap"
           type="tk.mybatis.simple.model.SysRole">

    <association property="privilegeList" columnPrefix="privilege_"
                 resultMap="tk.mybatis.simple.mapper.PrivilegeMapper.privilegeMap"/>
</resultMap>

最后还要修改 UserMapper.xml 中的 userRo l e Li st Map , 代码如 下:

<resultMap id="userRoleListMap" extends="userMap"
           type="tk.mybatis.simple.model.SysUser">

    <collection property="roleList" columnPrefix="role_"
                resultMap="tk.mybatis.simple.mapper.RoleMapper.rolePrivilegeListMap"/>

</resultMap>

为了得到权限信息 , 还需要修改 SQL 进行关联,代码如下:

<select id="selectAllUserAndRoles" resultMap="userRoleListMap">
    SELECT
      u.id,
      u.user_name,
      u.user_password,
      u.user_info,
      u.user_email,
      u.head_img,
      u.create_time,
      r.id "role_id",
      r.role_name "role_role_name",
      r.enabled "role_enabled",
      r.create_by "role_create_by",
      r.create_time "role_create_time",
      p.id "role_privilege_id",
      p.privilege_name "role_privilege_privilege_name",
      p.privilege_url "role_privilege_privilege_url"
    FROM  sys_user u
    INNER JOIN sys_user_role ur on u.id = ur.user_id
    INNER JOIN sys_role r ON r.id  = ur.role_id
    INNER JOIN sys_role_privilege rp ON rp.role_id = r.id
    INNER JOIN sys_privilege p ON p.id = rp.privilege_id
</select>

这里要特别注意 sys_privilege 表中列的别名,因为 sys_privilege 嵌套在rolePrivilegeListMap 中,而 rolePrivilegeListMap 的前缀是“ role_ ”,所以rolePrivilegeListMap 中 privilegeMap 的前缀就变成了“ role_privilege_”在嵌套中,这个前缀需要叠加, 一定不要写错。配置好 SQL 后,修改测试方法中的循环部分,代码如下:

@Test
public void testSelectAllUserAndRoles(){
    SqlSession sqlSession = getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<SysUser> userList = userMapper.selectAllUserAndRoles();
        System.out.println("用户数量:"+userList.size());
        userList.forEach((user)->{
            System.out.println("用户名:"+user.getUserName());
            List<SysRole> roleList = user.getRoleList();
            roleList.forEach((role)->{
                System.out.println("角色名:"+role.getRoleName());
                List<SysPrivilege> privilegeList = role.getPrivilegeList();
                privilegeList.forEach((p)->{
                    System.out.println(p.getPrivilegeName());
                });
            });
        });
    }finally {
        sqlSession.close();
    }
}

测试结果如下:

用户数量:2
用户名:admin
角色名:管理员
用户管理
系统日志
角色管理
角色名:普通用户
人员维护
单位维护
用户名:test
角色名:普通用户
人员维护
单位维护

第二种解决方案:collection 集合的嵌套查询

在 SysUser 类中增加 roleList 属性用于存储用户对应的多个角色 ,代码如下:

/**
 * 一个角色对应多个权限
 */
List<SysPrivilege> privilegeList;

public List<SysPrivilege> getPrivilegeList() {
    return privilegeList;
}

public void setPrivilegeList(List<SysPrivilege> privilegeList) {
    this.privilegeList = privilegeList;
}

在PrivilegeMapper.xml中添加如 下方法:

<select id="selectPrivilegeByRoleId" resultMap="privilegeMap">
    SELECT
      p.*
    FROM sys_privilege p
    INNER JOIN sys_role_privilege rp on p.id = rp.privilege_id
    WHERE rp.role_id = #{roleId}
</select>

这个方法通过角色id获取该角色对应的所有权限信息,可 以在 PrivilegeMapper 接 口中增加相应的方法。这是一个很常见的方法 , 许多 时候都需要这样一个方法来获取角色包含的所有权限信息 。

在PrivilegeMapper.java 接口中增加如下代码:

/**
 * 根据roleId查询权限集合
 * @param roleId
 * @return
 */
List<SysPrivilege> selectPrivilegeByRoleId(Long roleId);

测试代码如下:

@Test
public void testSelectPrivilegeByRoleId() {
    SqlSession sqlSession = getSqlSession();
    try {
        PrivilegeMapper privilegeMapper = sqlSession.getMapper(PrivilegeMapper.class);
        List<SysPrivilege> privilegeList = privilegeMapper.selectPrivilegeByRoleId(1L);
        privilegeList.forEach((privilege)->{
            System.out.println(privilege.getPrivilegeName());
        });
    }finally {
        sqlSession.close();
    }
}

测试结果:

[DEBUG] 2018-04-30 18:51:21,341 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp on p.id = rp.privilege_id WHERE rp.role_id = ? 
[DEBUG] 2018-04-30 18:51:21,388 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 1(Long)
[TRACE] 2018-04-30 18:51:21,434 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, privilege_name, privilege_url
[TRACE] 2018-04-30 18:51:21,434 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, 用户管理, /users
[TRACE] 2018-04-30 18:51:21,434 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 3, 系统日志, /logs
[TRACE] 2018-04-30 18:51:21,450 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 2, 角色管理, /roles
[DEBUG] 2018-04-30 18:51:21,450 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 3
用户管理
系统日志
角色管理

下一步,在RoleMapper.xml中配置映射和对应的 查询方法 , 代码如下 :

<resultMap id="rolePrivilegeListMapSelect" extends="roleMap"
           type="tk.mybatis.simple.model.SysRole">

    <collection property="privilegeList"
                column="{roleId=id}"
                fetchType="lazy"
             select="tk.mybatis.simple.mapper.PrivilegeMapper.selectPrivilegeByRoleId"/>
</resultMap>


<select id="selectRoleByUserId" resultMap="rolePrivilegeListMapSelect">
    SELECT
      r.*
    FROM sys_role r
    INNER JOIN sys_user_role ur on r.id = ur.role_id
    where ur.user_id = #{userId}
</select>

在上面代码中要注意 column 属性配置的{roleId = id}, roleId 是select 指定方法selectPrivilegeByRoleId 查询中的参数, id 是当前查询 selectRoleByUserid 中查询出的角色 id 。

在RoleMapper.java中添加如下方法:

/**
 * 根据userId查询对应的角色信息
 * @return
 */
List<SysRole> selectRoleByUserId(Long id);

测试代码如下:

@Test
public void testSelectRoleByUserId(){
    SqlSession sqlSession = getSqlSession();
    try {
        RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
        List<SysRole> roleList = roleMapper.selectRoleByUserId(1L);

        roleList.forEach((role)->{
            System.out.println("角色名:"+role.getRoleName());
            List<SysPrivilege> privilegeList = role.getPrivilegeList();
            privilegeList.forEach((privilege)->{
                System.out.println("权限名:"+privilege.getPrivilegeName());
            });
        });

    }finally {
        sqlSession.close();
    }
}

测试结果如下:

[DEBUG] 2018-04-30 19:20:16,692 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT r.* FROM sys_role r INNER JOIN sys_user_role ur on r.id = ur.role_id where ur.user_id = ? 
[DEBUG] 2018-04-30 19:20:16,723 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 1(Long)
[TRACE] 2018-04-30 19:20:16,785 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, role_name, enabled, create_by, create_time
[TRACE] 2018-04-30 19:20:16,785 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, 管理员, 1, 1, 2018-04-24 14:34:34.0
[TRACE] 2018-04-30 19:20:16,830 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 2, 普通用户, 1, 1, 2018-04-24 15:08:34.0
[DEBUG] 2018-04-30 19:20:16,831 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 2
角色名:管理员
[DEBUG] 2018-04-30 19:20:16,833 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp on p.id = rp.privilege_id WHERE rp.role_id = ? 
[DEBUG] 2018-04-30 19:20:16,834 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 1(Long)
[TRACE] 2018-04-30 19:20:16,868 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, privilege_name, privilege_url
[TRACE] 2018-04-30 19:20:16,868 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, 用户管理, /users
[TRACE] 2018-04-30 19:20:16,868 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 3, 系统日志, /logs
[TRACE] 2018-04-30 19:20:16,868 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 2, 角色管理, /roles
[DEBUG] 2018-04-30 19:20:16,868 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 3
权限名:用户管理
权限名:系统日志
权限名:角色管理
角色名:普通用户
[DEBUG] 2018-04-30 19:20:16,868 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp on p.id = rp.privilege_id WHERE rp.role_id = ? 
[DEBUG] 2018-04-30 19:20:16,868 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 2(Long)
[TRACE] 2018-04-30 19:20:16,915 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, privilege_name, privilege_url
[TRACE] 2018-04-30 19:20:16,916 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 4, 人员维护, /persons
[TRACE] 2018-04-30 19:20:16,917 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 5, 单位维护, /companies
[DEBUG] 2018-04-30 19:20:16,918 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 2
权限名:人员维护
权限名:单位维护

终于要轮到顶层的用户信息了

在UserMapper.xml中添加如下映射和查询,代码如下:

<resultMap id="rolePrivilegeListMapSelect" extends="roleMap"
           type="tk.mybatis.simple.model.SysRole">

    <collection property="privilegeList"
                column="{roleId=id}"
                fetchType="lazy"
            select="tk.mybatis.simple.mapper.PrivilegeMapper.selectPrivilegeByRoleId"/>
</resultMap>

<select id="selectAllUserAndRolesSelect" resultMap="rolePrivilegeListMapSelect">
    SELECT
      u.*
    FROM sys_user u
    where u.id = {id}
</select>

在UserMapper中添加如下方法:

/**
 * 根据id查询用户信息及其对应的所有角色信息和角色对应的权限信息
 * @param id
 * @return
 */
SysUser selectAllUserAndRolesSelect(Long id);

测试代码如下:

@Test
public void  testSelectAllUserAndRolesSelect(){
    SqlSession sqlSession = getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        SysUser user = userMapper.selectAllUserAndRolesSelect(1L);
        System.out.println(user.getUserName());
        System.out.println("---------------------");
        List<SysRole> roleList = user.getRoleList();
        System.out.println(roleList.size());
        System.out.println("-----------------------------------");
        roleList.forEach((role)->{
            List<SysPrivilege> privilegeList = role.getPrivilegeList();
            privilegeList.forEach((p)->{
                System.out.println(p.getPrivilegeName());
            });
        });
    }finally {
        sqlSession.close();
    }
}

测试结果如下:

[DEBUG] 2018-04-30 21:53:14,362 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT u.* FROM sys_user u where u.id = ? 
[DEBUG] 2018-04-30 21:53:14,409 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 1(Long)
[TRACE] 2018-04-30 21:53:14,456 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, user_name, user_password, user_email, user_info, head_img, create_time
[TRACE] 2018-04-30 21:53:14,456 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, admin, 123456, [email protected], <<BLOB>>, <<BLOB>>, 2018-04-24 17:08:34.0
[DEBUG] 2018-04-30 21:53:14,503 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 1
admin
---------------------
[DEBUG] 2018-04-30 21:53:14,503 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT r.* FROM sys_role r INNER JOIN sys_user_role ur on r.id = ur.role_id where ur.user_id = ? 
[DEBUG] 2018-04-30 21:53:14,518 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 1(Long)
[TRACE] 2018-04-30 21:53:14,549 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, role_name, enabled, create_by, create_time
[TRACE] 2018-04-30 21:53:14,549 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, 管理员, 1, 1, 2018-04-24 14:34:34.0
[TRACE] 2018-04-30 21:53:14,549 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 2, 普通用户, 1, 1, 2018-04-24 15:08:34.0
[DEBUG] 2018-04-30 21:53:14,549 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 2
2
-----------------------------------
[DEBUG] 2018-04-30 21:53:14,549 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp on p.id = rp.privilege_id WHERE rp.role_id = ? 
[DEBUG] 2018-04-30 21:53:14,565 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 1(Long)
[TRACE] 2018-04-30 21:53:14,596 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, privilege_name, privilege_url
[TRACE] 2018-04-30 21:53:14,596 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 1, 用户管理, /users
[TRACE] 2018-04-30 21:53:14,596 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 3, 系统日志, /logs
[TRACE] 2018-04-30 21:53:14,596 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 2, 角色管理, /roles
[DEBUG] 2018-04-30 21:53:14,596 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 3
用户管理
系统日志
角色管理
[DEBUG] 2018-04-30 21:53:14,596 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==>  Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp on p.id = rp.privilege_id WHERE rp.role_id = ? 
[DEBUG] 2018-04-30 21:53:14,596 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
==> Parameters: 2(Long)
[TRACE] 2018-04-30 21:53:14,643 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==    Columns: id, privilege_name, privilege_url
[TRACE] 2018-04-30 21:53:14,643 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 4, 人员维护, /persons
[TRACE] 2018-04-30 21:53:14,643 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)
<==        Row: 5, 单位维护, /companies
[DEBUG] 2018-04-30 21:53:14,643 method:org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)
<==      Total: 2
人员维护
单位维护

这里可以看到懒加载的作用。

猜你喜欢

转载自blog.csdn.net/guo20082200/article/details/80152578