main方法 如何去掉http debug日志_在MyBatis中如何使用collection标签实现嵌套查询?...
# 需求升級
在上篇博客《一對多的關系,在MyBatis中如何映射?》中,我們實現了需求:根據用戶id查詢用戶信息的同時獲取用戶擁有的角色。
因為角色可以擁有多個權限,所以本篇博客我們升級需求為:根據用戶id查詢用戶信息的同時獲取用戶擁有的角色以及角色包含的權限。
# 實現方式
因為我們需要使用到權限表的映射,所以我們需要先在SysPrivilegeMapper.xml中添加如下映射:
<resultMap id="sysPrivilegeMap" type="com.zwwhnly.mybatisaction.model.SysPrivilege"> <id property="id" column="id"/> <result property="privilegeName" column="privilege_name"/> <result property="privilegeUrl" column="privilege_url"/>resultMap>一般情況下不建議修改數據庫表對應的實體類,所以這里我們新建類SysRoleExtend,讓它繼承SysRole類,并添加如下字段:
package com.zwwhnly.mybatisaction.model;import java.util.List;public class SysRoleExtend extends SysRole { /** * 角色包含的權限列表 */ private List sysPrivilegeList; public ListgetSysPrivilegeList() { return sysPrivilegeList; } public void setSysPrivilegeList(List sysPrivilegeList) { this.sysPrivilegeList = sysPrivilegeList; }}然后在SysRoleMapper.xml中新建如下映射:
<resultMap id="rolePrivilegeListMap" extends="roleMap" type="com.zwwhnly.mybatisaction.model.SysRoleExtend"> <collection property="sysPrivilegeList" columnPrefix="privilege_" resultMap="com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap"/>resultMap>這里的roleMap我們在之前的博客中已經定義過,代碼如下:
<resultMap id="roleMap" type="com.zwwhnly.mybatisaction.model.SysRole"> <id 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"/>resultMap>com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap就是我們剛剛在SysPrivilegeMapper.xml中新建的映射sysPrivilegeMap。
然后,需要將上篇博客中的userRoleListMap修改為:
<resultMap id="userRoleListMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend" extends="sysUserMap"> <collection property="sysRoleList" columnPrefix="role_" resultMap="com.zwwhnly.mybatisaction.mapper.SysRoleMapper.rolePrivilegeListMap"> collection>resultMap>并且要修改上篇博客中id為selectAllUserAndRoles的select標簽代碼,因為要關聯角色權限關系表和權限表:
SELECT u.id, u.user_name, u.user_password, u.user_email, 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 ur.role_id = r.id INNER JOIN sys_role_privilege rp ON rp.role_id = r.id INNER JOIN sys_privilege p ON p.id = rp.privilege_id注意事項:
這里sys_privilege表的列名的別名前綴為role_privilege_,這是因為userRoleListMap中collection的columnPrefix屬性為role_,并且指定的com.zwwhnly.mybatisaction.mapper.SysRoleMapper.rolePrivilegeListMap中collection的columnPrefix屬性為privilege_,所以這里的前綴需要疊加,就變成了role_privilege_。
# 單元測試
修改上篇博客中建的測試方法testSelectAllUserAndRoles()代碼為:
@Testpublic void testSelectAllUserAndRoles() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); List sysUserList = sysUserMapper.selectAllUserAndRoles(); System.out.println("用戶數:" + sysUserList.size()); for (SysUserExtend sysUser : sysUserList) { System.out.println("用戶名:" + sysUser.getUserName()); for (SysRoleExtend sysRoleExtend : sysUser.getSysRoleList()) { System.out.println("角色名:" + sysRoleExtend.getRoleName()); for (SysPrivilege sysPrivilege : sysRoleExtend.getSysPrivilegeList()) { System.out.println("權限名:" + sysPrivilege.getPrivilegeName()); } } } } finally { sqlSession.close(); }}運行測試代碼,測試通過,輸出日志如下:
DEBUG [main] - ==> Preparing: SELECT u.id, u.user_name, u.user_password, u.user_email, 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 ur.role_id = r.id INNER JOIN sys_role_privilege rp ON rp.role_id = r.id INNER JOIN sys_privilege p ON p.id = rp.privilege_idDEBUG [main] - ==> Parameters:TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_time, role_id, role_role_name, role_enabled, role_create_by, role_create_time, role_privilege_id, role_privilege_privilege_name, role_privilege_privilege_urlTRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0, 1, 管理員, 1, 1, 2019-06-27 18:21:12.0, 1, 用戶管理, /usersTRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0, 1, 管理員, 1, 1, 2019-06-27 18:21:12.0, 2, 角色管理, /rolesTRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0, 1, 管理員, 1, 1, 2019-06-27 18:21:12.0, 3, 系統日志, /logsTRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用戶, 1, 1, 2019-06-27 18:21:12.0, 4, 人員維護, /personsTRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用戶, 1, 1, 2019-06-27 18:21:12.0, 5, 單位維護, /companiesTRACE [main] - <== Row: 1001, test, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用戶, 1, 1, 2019-06-27 18:21:12.0, 4, 人員維護, /personsTRACE [main] - <== Row: 1001, test, 123456, test@mybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用戶, 1, 1, 2019-06-27 18:21:12.0, 5, 單位維護, /companiesDEBUG [main] - <== Total: 7用戶數:2用戶名:admin角色名:管理員權限名:用戶管理權限名:角色管理權限名:系統日志角色名:普通用戶權限名:人員維護權限名:單位維護用戶名:test角色名:普通用戶權限名:人員維護權限名:單位維護從日志可以看出,不僅查詢出了用戶擁有的角色信息,也查詢出了角色包含的權限信息。
# 延遲加載
有的同學可能會說,返回的角色信息和權限信息我不一定用啊,每次關聯這么多表查詢一次數據庫,好影響性能啊,能不能在我使用到角色信息即獲取sysRoleList屬性時再去數據庫查詢呢?答案當然是能,那么如何實現呢?
實現延遲加載需要使用collection標簽的fetchType屬性,該屬性有lazy和eager兩個值,分別代表延遲加載和積極加載。
由于需要根據角色Id獲取該角色對應的所有權限信息,所以我們要先在SysPrivilegeMapper.xml中定義如下查詢:
<select id="selectPrivilegeByRoleId" resultMap="sysPrivilegeMap"> SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp ON rp.privilege_id = p.id WHERE rp.role_id = #{roleId}select>然后在SysRoleMapper.xml中添加如下查詢:
<resultMap id="rolePrivilegeListMapSelect" extends="roleMap" type="com.zwwhnly.mybatisaction.model.SysRoleExtend"> <collection property="sysPrivilegeList" fetchType="lazy" column="{roleId=id}" select="com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.selectPrivilegeByRoleId"/>resultMap><select id="selectRoleByUserId" resultMap="rolePrivilegeListMapSelect"> 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>上面的column="{roleId=id}"中,roleId指的是select指定的方法selectPrivilegeByRoleId的參數,id指的是查詢selectRoleByUserId中查詢出的角色id。
然后在SysUserMapper.xml中添加如下查詢:
<resultMap id="userRoleListMapSelect" extends="sysUserMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend"> <collection property="sysRoleList" fetchType="lazy" select="com.zwwhnly.mybatisaction.mapper.SysRoleMapper.selectRoleByUserId" column="{userId=id}"/>resultMap><select id="selectAllUserAndRolesSelect" resultMap="userRoleListMapSelect"> SELECT u.id, u.user_name, u.user_password, u.user_email, u.create_time FROM sys_user u WHERE u.id = #{id}select>上面的column="{userId=id}"中,userId指的是select指定的方法selectRoleByUserId的參數,id指的是查詢selectAllUserAndRolesSelect中查詢出的用戶id。
然后,在SysUserMapper接口中,添加如下方法:
/** * 通過嵌套查詢獲取指定用戶的信息以及用戶的角色和權限信息 * * @param id * @return */SysUserExtend selectAllUserAndRolesSelect(Long id);最后,在SysUserMapperTest類中添加如下測試方法:
@Testpublic void testSelectAllUserAndRolesSelect() { SqlSession sqlSession = getSqlSession(); try { SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class); SysUserExtend sysUserExtend = sysUserMapper.selectAllUserAndRolesSelect(1L); System.out.println("用戶名:" + sysUserExtend.getUserName()); for (SysRoleExtend sysRoleExtend : sysUserExtend.getSysRoleList()) { System.out.println("角色名:" + sysRoleExtend.getRoleName()); for (SysPrivilege sysPrivilege : sysRoleExtend.getSysPrivilegeList()) { System.out.println("權限名:" + sysPrivilege.getPrivilegeName()); } } } finally { sqlSession.close(); }}運行測試方法,輸出日志如下:
DEBUG [main] - ==> Preparing: SELECT u.id, u.user_name, u.user_password, u.user_email, u.create_time FROM sys_user u WHERE u.id = ?DEBUG [main] - ==> Parameters: 1(Long)TRACE [main] - <== Columns: id, user_name, user_password, user_email, create_timeTRACE [main] - <== Row: 1, admin, 123456, admin@mybatis.tk, 2019-06-27 18:21:07.0DEBUG [main] - <== Total: 1用戶名:adminDEBUG [main] - ==> 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 = ?DEBUG [main] - ==> Parameters: 1(Long)TRACE [main] - <== Columns: id, role_name, enabled, create_by, create_timeTRACE [main] - <== Row: 1, 管理員, 1, 1, 2019-06-27 18:21:12.0TRACE [main] - <== Row: 2, 普通用戶, 1, 1, 2019-06-27 18:21:12.0DEBUG [main] - <== Total: 2角色名:管理員DEBUG [main] - ==> Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp ON rp.privilege_id = p.id WHERE rp.role_id = ?DEBUG [main] - ==> Parameters: 1(Long)TRACE [main] - <== Columns: id, privilege_name, privilege_urlTRACE [main] - <== Row: 1, 用戶管理, /usersTRACE [main] - <== Row: 2, 角色管理, /rolesTRACE [main] - <== Row: 3, 系統日志, /logsDEBUG [main] - <== Total: 3權限名:用戶管理權限名:角色管理權限名:系統日志角色名:普通用戶DEBUG [main] - ==> Preparing: SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp ON rp.privilege_id = p.id WHERE rp.role_id = ?DEBUG [main] - ==> Parameters: 2(Long)TRACE [main] - <== Columns: id, privilege_name, privilege_urlTRACE [main] - <== Row: 4, 人員維護, /personsTRACE [main] - <== Row: 5, 單位維護, /companiesDEBUG [main] - <== Total: 2權限名:人員維護權限名:單位維護仔細分析上面的日志,會發現只有在使用到了角色信息和權限信息時,才執行了對應的數據庫查詢。
需要注意的是,延遲加載依賴于MyBatis全局配置中的aggressiveLazyLoading,在之前的博客講解association標簽時,我們已經將其配置為了false,所以這里的執行結果符合我們的預期:
<settings> <setting name="aggressiveLazyLoading" value="false"/>settings>關于該參數的詳細講解,請查看MyBatis從入門到精通(十):使用association標簽實現嵌套查詢。
# 總結
使用collection標簽實現嵌套查詢,用到的屬性總結如下:
1)select:另一個映射查詢的id,MyBatis會額外執行這個查詢獲取嵌套對象的結果。
2)column:將主查詢中列的結果作為嵌套查詢的參數,配置方式如column="{prop1=col1,prop2=col2}",prop1和prop2將作為嵌套查詢的參數。
3)fetchType:數據加載方式,可選值為lazy和eager,分別為延遲加載和積極加載。
4)如果要使用延遲加載,除了將fetchType設置為lazy,還需要注意全局配置aggressiveLazyLoading的值應該為false。這個參數在3.4.5版本之前默認值為ture,從3.4.5版本開始默認值改為false。
5)MyBatis提供的lazyLoadTriggerMethods參數,支持在觸發某方法時直接觸發延遲加載屬性的查詢,如equals()方法。
#? 源碼及參考
源碼地址:https://github.com/zwwhnly/mybatis-action.git,歡迎下載。
劉增輝《MyBatis從入門到精通》
作者:申城異鄉人
來源:https://www.cnblogs.com/zwwhnly/p/11201185.html
?往期推薦?
?
- 一個小需求,能夠做到月活躍用戶5000萬,就是真牛逼!
- 如何在面試中介紹自己的項目經驗?
- 百度面試官:如果叫你設計一個短鏈接系統,你會從那些方面來提高性能呢?
點擊
總結
以上是生活随笔為你收集整理的main方法 如何去掉http debug日志_在MyBatis中如何使用collection标签实现嵌套查询?...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql排序行号_mysql 取得行号
- 下一篇: python 切片器_PowerBI-将