【筆記】Mybatis高階查詢(五)--使用resultMap的<collection>進行巢狀查詢及延遲載入
阿新 • • 發佈:2018-11-01
下面例子通過
<collection>
實現一個通過使用者編號查詢使用者下面的角色及許可權的需求,支援延遲載入。下面以自下而上的過程來實現這樣的巢狀查詢功能。並且這個自下而上的過程中每一個方法都是獨立可用的方法。上層的結果都以下層方法為基礎。所有物件都設定為延遲載入。
- 在最底層許可權表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>
- 在SysPrivilegeMapper介面中新增selectPriByRoleId方法
/** * 根據角色id查詢許可權 * @param roleId * @return */ List<SysPrivilege> selectPriByRoleId(Long roleId);
- 先測試一下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(); } }
- 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]
- 到了中間層sys_role角色表了。在SysRole類中增加許可權屬性privileges
private List<SysPrivilege> privileges; public List<SysPrivilege> getPrivileges() { return privileges; } public void setPrivileges(List<SysPrivilege> privileges) { this.privileges = privileges; }
- 在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>
- 在SysRoleMapper介面中增加selectRolesById方法
/** * 使用resultMap的<collection>標籤進行一對多查詢,根據使用者編號查角色 * @param id * @return */ List<SysRole> selectRolesById(Long userId);
- 在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(); } }
- 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]
- 最後到了項層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>
- 在SysUserMapper介面中增加selectUserById方法
/** * 使用resultMap的<collection>標籤進行一對多查詢,根據編號查使用者資訊 * @param id * @return */ SysUser selectUserById(Long id);
- 在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(); } }
- 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]
- 到此需求功能已實現,首先通過使用者ID:1001查詢使用者資訊,然後呼叫user.getRoles()觸發selectRolesById查詢獲取使用者1001的角色,再通過呼叫role.getPrivileges()將查出來的角色ID傳給selectPriByRoleId查詢角色的許可權資訊。引數的傳遞:id->userId->roleId