在RBAC權限系統設計過程中,假設一個用戶只有一個角色(當然實際系統並非如此)
序號 | 表名 | 對應實體 | 對應數據庫接口 | 對應mapper | 備注 |
1 | sys_user | SysUser | UserMapper.java | UserMapper.xml | 用戶表 |
2 | sys_role | SysRole | RoleMapper.java | RoleMapper.xml | 角色表 |
在SysUser實體添加角色屬性SysRole
SysUser.java
SysRole.java
一、自動映射處理一對一映射
查詢sql中通過別名讓Mybatis自動將值匹配到對應的字段上,簡單的別名如user_name匹配到userName,除此之外還支持復雜的屬性映射,可以多層嵌套,例如將role.role_name映射到roleName上。
在UserMapper.xml添加select,如下
注意上述方法中sys_role查詢列的別名都是"role."前綴,通過這種方式將role的屬性都映射到了SysUser的role屬性上。
在UserMapper.java接口中添加對應查詢接口,如下
一對一映射查詢完成,當前查詢返回的SysUser實例包含起對應的SysRole內容。
二、使用resultMap配置一對一映射
在 UserMapper.xml 中增加如下的 resultMap 配置。
也可以通過resultMap的extends屬性優化寫法,如下
這種配置和上一節自動映射方式相似的地方在於,role中的 property 配置部分使用"role."前綴。在 column 部分,為了避免不同表中存在相同的列,所有可能重名的列都增加了"role"前綴。使用這種方式配置的時候,還需要在查詢時設置不同的別名。
在SysUserMapper.xml添加查詢selectUserAndRoleByid2
在UserMapper.java接口中添加對應查詢接口,如下
三、使用resultMap的association標簽配置一對一映射
在 resultMap 中,association標簽用於和一個復雜的類型進行關聯,即用於一對一的關聯配置 。
修改userRole標簽如下
association常用標簽包含以下屬性:
property :對應實體類中的屬性名,必填項。
javaType : 屬性對應的 Java 類型 。
resultMap : 可以直接使用現有的 resultMap ,而不需要在這里配置。
columnPrefix :查詢列的前綴,配置前綴后,在子標簽配置result 的.column時可以省略前綴。
association可以配置已經存在的resultMap進而優化提取公共代碼,如下在UserMapper.xml
當前userRoleMap定義在UserMapper.xml,合理的方式應該定義在RoleMapper.xml,對應將association引用resultMap的地方修改為對應的全路徑即可(MyBatis默認會給roleMap添加當前命名空間的前綴)。
resultMap="com.chl.mapper.RoleMapper.userRoleMap"
在UserMapper.xml添加查詢標簽
三、使用association標簽的嵌套查詢
association 標簽的嵌套查詢常用的屬性如下:
select :另一個映射查詢的 id, MyBatis 會額外執行這個查詢獲取嵌套對象的結果。
column :列名(或別名),將主查詢中列的結果作為嵌套查詢的 參數,配置方式如column={propl=coll , prop2=col2}, propl 和 prop2 將作為嵌套查詢的參數。
fetchType :數據加載方式,可選值為 lazy 和 eager,分別為延遲加載和積極加載,這個配置會覆蓋全局的 lazyLoadingEnabled 配置。
在UserMapper.xml創建resultMap和select
【說明】關聯查詢中已經去掉和sys_role相關的,角色信息由selectRoleById來查詢,這個查詢定義在RoleMapper.xml中。
【說明】當使用fetchType配置lazy時,為了阻止在查詢時調用setter方法還需在mybatis-config.xml進行如下配置,
當該參數設置為 true 時,對任意延遲屬性的調用會使帶有延遲加載屬性的對象完整加載,反之,每種屬性都將按需加載。這個參數默認為 true ,所以當查詢sys_user 過后並給 SysUser 對象賦值時,會調用該對象其他屬性的setter方法,這也會觸發上述規則,導致本該延遲加載的屬性直接加載
在RoleMapper.xml定義select
配置完成。
【其他說明】有些時候還是需要在觸發某方法時將所有的數據都加載進來,而我們己經將 aggressiveLazyLoading 設置為 false ,這種情況又該怎么解決呢?
MyBatis 仍然提供了參數 lazyLoadTriggerMethods 幫助解決這個問題,這個參數的含義是,當調用配置中的方法時,加載全部的延遲加載數據。
默認值為 ” eqals , clone ,hashCode,toString ” 。因此在使用默認值的情況下,只要調用其中一個方法就可以實現加載調用對象的全部數據。