【笔记】Mybatis高级查询(五)--使用resultMap的<collection>进行嵌套查询及延迟加载

下面例子通过<collection>实现一个通过用户编号查询用户下面的角色及权限的需求,支持延迟加载。下面以自下而上的过程来实现这样的嵌套查询功能。并且这个自下而上的过程中每一个方法都是独立可用的方法。上层的结果都以下层方法为基础。所有对象都设置为延迟加载。

  1. 在最底层权限表sys_privilege的映射文件SysPrivilegeMapper.xml中添加selectPriByRoleId方法,实现通过角色编号查询对应权限
    <!-- 根据角色id查询权限 -->
      <select id="selectPriByRoleId" resultMap="privilegeMap">
      	select id, privilege_name, privilege_url
        from sys_privilege p
        inner join sys_role_privilege rp on rp.privilege_id = p.id
        where rp.role_id = #{roleId}
      </select>
    
  2. 在SysPrivilegeMapper接口中添加selectPriByRoleId方法
    	/**
         * 根据角色id查询权限
         * @param roleId
         * @return
         */
        List<SysPrivilege> selectPriByRoleId(Long roleId);
    
  3. 先测试一下selectPriByRoleId方法,在PrivilegeMaperTest中增加selectPriByRoleId对应测试方法
    	@Test
    	public void testSelectPriByRoleId() {
    		// 获取SqlSession
    		SqlSession sqlSession = openSession();
    		try {
    			// 获取PrivilegeMapper接口
    			SysPrivilegeMapper privilegeMapper = sqlSession.getMapper(SysPrivilegeMapper.class);
    			
    			// 调用selectPriByRoleId方法
    			List<SysPrivilege> privileges = privilegeMapper.selectPriByRoleId(1L);
    			
    			// user不为空
    			Assert.assertNotNull(privileges);
    			
    			System.out.println();
    			for (SysPrivilege privilege : privileges) {
    				System.out.println(privilege);
    			}
    		} finally {
    			sqlSession.close();
    		}
    	}
    
  4. selectPriByRoleId方法的测试结果,通过结果查看selectPriByRoleId方法可以单独使用
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - ==>  Preparing: select id, privilege_name, privilege_url from sys_privilege p inner join sys_role_privilege rp on rp.privilege_id = p.id where rp.role_id = ? 
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - ==> Parameters: 1(Long)
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==    Columns: id, privilege_name, privilege_url
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==        Row: 1, 用户管理, /users
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==        Row: 2, 角色管理, /roles
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==        Row: 3, 系统日志, /logs
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==      Total: 3
    
    SysPrivilege [id=1, privilegeName=用户管理, privilegeUrl=/users]
    SysPrivilege [id=2, privilegeName=角色管理, privilegeUrl=/roles]
    SysPrivilege [id=3, privilegeName=系统日志, privilegeUrl=/logs]
    
  5. 到了中间层sys_role角色表了。在SysRole类中增加权限属性privileges
    	private List<SysPrivilege> privileges;
    
    	public List<SysPrivilege> getPrivileges() {
    		return privileges;
    	}
    
    	public void setPrivileges(List<SysPrivilege> privileges) {
    		this.privileges = privileges;
    	}
    
  6. 在SysRoleMapper.xml中配置映射rolePrisMapSel和对应的查询方法selectRolesById
      <!-- 使用resultMap的<collection>标签进行一对多查询,根据用户查询角色信息 -->
      <resultMap id="rolePrisMapSel" extends="roleMap" type="ex.mybatis.rbac.model.SysRole">
        
        <!-- 角色权限的集合 -->
        <collection property="privileges" fetchType="lazy" column="{roleId=id}" 
        select="ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId" />
      </resultMap>
      
      <!-- 使用resultMap的<collection>标签进行一对多查询,查询角色对应的权限 -->
      <select id="selectRolesById" resultMap="rolePrisMapSel">
        select 
    	    r.id, 
    	    r.role_name, 
    	    r.enabled, 
    	    r.create_by, 
    	    r.create_time
        from sys_role r
        inner join sys_user_role ur on ur.role_id = r.id
        where ur.user_id = #{userId}
      </select>
    
  7. 在SysRoleMapper接口中增加selectRolesById方法
    	/**
         * 使用resultMap的<collection>标签进行一对多查询,根据用户编号查角色
         * @param id
         * @return
         */
        List<SysRole> selectRolesById(Long userId);
    
  8. 在RoleMaperTest中增加selectRolesById对应的测试方法
    	@Test
    	public void testSelectRolesById() {
    		// 获取SqlSession
    		SqlSession sqlSession = openSession();
    		try {
    			// 获取SysRoleMapper接口
    			SysRoleMapper roleMapper = sqlSession.getMapper(SysRoleMapper.class);
    			
    			// 调用selectRolesById方法
    			List<SysRole> roles = roleMapper.selectRolesById(1L);
    			
    			System.out.println("角色数:" + roles.size());
    			for (SysRole role : roles) {
    				System.out.println("调用role.getPrivileges()获取权限");
    				System.out.println("\n角色:" + role);
    				for (SysPrivilege privilege : role.getPrivileges()) {
    					System.out.println("--权限:" + privilege);
    				}
    				System.out.println();
    			}
    			
    			System.out.println();
    		} finally {
    			sqlSession.close();
    		}
    	}
    
  9. selectRolesById测试结果,可以看到用户1001有一个角色2,然后角色2有2个权限。在调用了role.getPrivileges()的时候才用roleId=2去查询权限信息。因为使用了延时加载。
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - ==>  Preparing: select r.id, r.role_name, r.enabled, r.create_by, r.create_time from sys_role r inner join sys_user_role ur on ur.role_id = r.id where ur.user_id = ? 
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - ==> Parameters: 1001(Long)
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - <==    Columns: id, role_name, enabled, create_by, create_time
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - <==        Row: 2, 普通用户, 0, 1, 2018-10-01 18:27:37.0
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - <==      Total: 1
    角色数:1
    调用role.getPrivileges()
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - ==>  Preparing: select id, privilege_name, privilege_url from sys_privilege p inner join sys_role_privilege rp on rp.privilege_id = p.id where rp.role_id = ? 
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - ==> Parameters: 2(Long)
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==    Columns: id, privilege_name, privilege_url
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==        Row: 4, 人员维护, /persons
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==        Row: 5, 单位维护, /companies
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==      Total: 2
    
    角色:SysRole [id=2, roleName=普通用户, enabled=disabled, createBy=1, createTime=Mon Oct 01 18:27:37 CST 2018]
    --权限:SysPrivilege [id=4, privilegeName=人员维护, privilegeUrl=/persons]
    --权限:SysPrivilege [id=5, privilegeName=单位维护, privilegeUrl=/companies]
    
  10. 最后到了项层sys_user了,通过用户id查询用户信息,在SysUserMapper.xml中增加配置映射userRolesMapSel和对应的查询方法selectUserById
      <!-- 使用resultMap的<collection>标签进行一对多查询 ,根据编号查用户信息-->
      <resultMap id="userRolesMapSel" extends="userMap" type="ex.mybatis.rbac.model.SysUser">
        
        <!-- 角色的集合 -->
        <collection property="roles" fetchType="lazy" column="{userId=id}" 
        select="ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById"/>
      </resultMap>
      
      <!-- 使用resultMap的<collection>标签进行一对多查询,根据编号查用户信息 -->
      <select id="selectUserById" resultMap="userRolesMapSel">
        select 
    	    id, 
    	    user_name, 
    	    user_password, 
    	    user_email, 
    	    create_time, 
    	    user_info, 
    	    head_img
        from sys_user
        where id = #{id}
      </select>
    
  11. 在SysUserMapper接口中增加selectUserById方法
    	/**
         * 使用resultMap的<collection>标签进行一对多查询,根据编号查用户信息
         * @param id
         * @return
         */
        SysUser selectUserById(Long id);
    
  12. 在UserMaperTest中增加selectUserById对应的测试方法
    	@Test
    	public void testSelectUserById() {
    		// 获取SqlSession
    		SqlSession sqlSession = openSession();
    		try {
    			// 获取SysUserMapper接口
    			SysUserMapper userMapper = sqlSession.getMapper(SysUserMapper.class);
    			
    			// 调用selectUserById方法
    			SysUser user = userMapper.selectUserById(1L);
    			
    			// user不为空
    			Assert.assertNotNull(user);
    			
    			// 查询用户下有多少角色
    			System.out.println("\n调用user.getRoles()获取角色");
    			List<SysRole> roles = user.getRoles();
    			System.out.println("角色数:" + roles.size());
    			
    			for (SysRole role : roles) {
    				System.out.println("\n调用role.getPrivileges()获取权限");
    				for (SysPrivilege privilege : role.getPrivileges()) {
    					System.out.println("--权限:" + privilege);
    				}
    			}
    		} finally {
    			sqlSession.close();
    		}
    	}
    
  13. selectUserById测试结果
    [ex.mybatis.rbac.mapper.SysUserMapper.selectUserById] - ==>  Preparing: select id, user_name, user_password, user_email, create_time, user_info, head_img from sys_user where id = ? 
    [ex.mybatis.rbac.mapper.SysUserMapper.selectUserById] - ==> Parameters: 1001(Long)
    [ex.mybatis.rbac.mapper.SysUserMapper.selectUserById] - <==    Columns: id, user_name, user_password, user_email, create_time, user_info, head_img
    [ex.mybatis.rbac.mapper.SysUserMapper.selectUserById] - <==        Row: 1001, test, 123456, [email protected], 2018-10-02 17:17:11.0, <<BLOB>>, <<BLOB>>
    [ex.mybatis.rbac.mapper.SysUserMapper.selectUserById] - <==      Total: 1
    
    调用user.getRoles()获取角色
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - ==>  Preparing: select r.id, r.role_name, r.enabled, r.create_by, r.create_time from sys_role r inner join sys_user_role ur on ur.role_id = r.id where ur.user_id = ? 
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - ==> Parameters: 1001(Long)
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - <==    Columns: id, role_name, enabled, create_by, create_time
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - <==        Row: 2, 普通用户, 0, 1, 2018-10-01 18:27:37.0
    [ex.mybatis.rbac.mapper.SysRoleMapper.selectRolesById] - <==      Total: 1
    角色数:1
    
    调用role.getPrivileges()获取权限
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - ==>  Preparing: select id, privilege_name, privilege_url from sys_privilege p inner join sys_role_privilege rp on rp.privilege_id = p.id where rp.role_id = ? 
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - ==> Parameters: 2(Long)
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==    Columns: id, privilege_name, privilege_url
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==        Row: 4, 人员维护, /persons
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==        Row: 5, 单位维护, /companies
    [ex.mybatis.rbac.mapper.SysPrivilegeMapper.selectPriByRoleId] - <==      Total: 2
    
    角色:SysRole [id=2, roleName=普通用户, enabled=disabled, createBy=1, createTime=Mon Oct 01 18:27:37 CST 2018]
    --权限:SysPrivilege [id=4, privilegeName=人员维护, privilegeUrl=/persons]
    --权限:SysPrivilege [id=5, privilegeName=单位维护, privilegeUrl=/companies]
    
  14. 到此需求功能已实现,首先通过用户ID:1001查询用户信息,然后调用user.getRoles()触发selectRolesById查询获取用户1001的角色,再通过调用role.getPrivileges()将查出来的角色ID传给selectPriByRoleId查询角色的权限信息。参数的传递:id->userId->roleId

猜你喜欢

转载自blog.csdn.net/q283614346/article/details/83279877