最近在讀劉增輝老師所著的《MyBatis從入門到精通》一書,很有收穫,於是將自己學習的過程以部落格形式輸出,如有錯誤,歡迎指正,如幫助到你,不勝榮幸!
本篇部落格主要講解鑑別器對映discriminator標籤的簡單用法。
1. 明確需求
在設計之初,sys_role表的enabled欄位有2個可選值,其中1代表啟用,0 代表禁用,當狀態啟用時就有對應的許可權資訊,當狀態禁用時就沒有對應的許可權資訊,只需查詢出角色資訊即可。
所以我們的需求為:根據使用者id查詢使用者擁有的角色列表,如果角色是啟用的,就繼續查詢出角色對應的許可權列表,如果角色是禁用的,就不需要查詢對應的許可權列表。
2. 實現方式
首先,我們需要在SysRoleMapper.xml中新建角色表的對映roleMapExtend,注意這裡我們使用的是之前新建的擴充套件類SysRoleExtend:
<resultMap id="roleMapExtend" type="com.zwwhnly.mybatisaction.model.SysRoleExtend">
<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>
然後回顧下上篇部落格中使用到的rolePrivilegeListMapSelect對映,因為接下來會用到:
<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>
接下來新建本篇部落格的主人公對映rolePrivilegeListMapChoose和對應的查詢語句:
<resultMap id="rolePrivilegeListMapChoose"
type="com.zwwhnly.mybatisaction.model.SysRoleExtend">
<discriminator column="enabled" javaType="int">
<case value="1" resultMap="rolePrivilegeListMapSelect"/>
<case value="0" resultMap="roleMapExtend"/>
</discriminator>
</resultMap>
<select id="selectRoleByUserIdChoose" resultMap="rolePrivilegeListMapChoose">
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>
discriminator標籤常用的2個屬性講解:
- column:設定要進行鑑別比較值的列名。
- javaType:指定列的型別,保證使用相同的Java型別來比較值。
discriminator標籤可以有1個或多個case標籤,case標籤包含以下3個屬性:
- value:該值為discriminator標籤column屬性用來匹配的值。
- resultMap:當column的值和value的值匹配時,可以配置使用resultMap指定的對映,resultMap優先順序高於resultType。
- resultType:當column的值和value的值匹配時,用於配置使用resultType指定的對映。
case標籤下面可以包含的標籤和resultMap一樣,用法也一樣。
然後在SysRoleMapper介面中新增如下方法:
/**
* 根據使用者id獲取使用者的角色資訊
*
* @param userId
* @return
*/
List<SysRoleExtend> selectRoleByUserIdChoose(Long userId);
3. 單元測試
在SysRoleMapperTest測試類中新增如下測試方法:
@Test
public void testSelectRoleByUserIdChoose() {
SqlSession sqlSession = getSqlSession();
try {
SysRoleMapper sysRoleMapper = sqlSession.getMapper(SysRoleMapper.class);
// 將id=2的角色的enabled賦值為0
SysRole sysRole = sysRoleMapper.selectById(2L);
sysRole.setEnabled(0);
sysRoleMapper.updateById(sysRole);
// 獲取使用者id為1的角色
List<SysRoleExtend> sysRoleExtendList = sysRoleMapper.selectRoleByUserIdChoose(1L);
for (SysRoleExtend item : sysRoleExtendList) {
System.out.println("角色名:" + item.getRoleName());
if (item.getId().equals(1L)) {
// 第一個角色存在許可權資訊
Assert.assertNotNull(item.getSysPrivilegeList());
} else if (item.getId().equals(2L)) {
// 第二個角色的許可權為null
Assert.assertNull(item.getSysPrivilegeList());
continue;
}
for (SysPrivilege sysPrivilege : item.getSysPrivilegeList()) {
System.out.println("許可權名:" + sysPrivilege.getPrivilegeName());
}
}
} finally {
sqlSession.close();
}
}
執行測試程式碼,測試通過,輸出日誌如下:
DEBUG [main] - ==> Preparing: SELECT id,role_name,enabled,create_by,create_time FROM sys_role WHERE id = ?
DEBUG [main] - ==> Parameters: 2(Long)
TRACE [main] - <== Columns: id, role_name, enabled, create_by, create_time
TRACE [main] - <== Row: 2, 普通使用者, 1, 1, 2019-06-27 18:21:12.0
DEBUG [main] - <== Total: 1
DEBUG [main] - ==> Preparing: UPDATE sys_role SET role_name = ?,enabled = ?,create_by=?, create_time=? WHERE id=?
DEBUG [main] - ==> Parameters: 普通使用者(String), 0(Integer), 1(Long), 2019-06-27 18:21:12.0(Timestamp), 2(Long)
DEBUG [main] - <== Updates: 1
DEBUG [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_time
TRACE [main] - <== Row: 1, 管理員, 1, 1, 2019-06-27 18:21:12.0
TRACE [main] - <== Row: 2, 普通使用者, 0, 1, 2019-06-27 18:21:12.0
DEBUG [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_url
TRACE [main] - <== Row: 1, 使用者管理, /users
TRACE [main] - <== Row: 2, 角色管理, /roles
TRACE [main] - <== Row: 3, 系統日誌, /logs
DEBUG [main] - <== Total: 3
許可權名:使用者管理
許可權名:角色管理
許可權名:系統日誌
角色名:普通使用者
從日誌可以看出,角色1是啟用的,所以又執行了一次查詢獲取角色的許可權列表,角色2是禁用的,所以沒有執行。
4. 原始碼及參考
原始碼地址:https://github.com/zwwhnly/mybatis-action.git,歡迎下載。
劉增輝《MyBatis從入門到精通》
5. 最後
打個小廣告,歡迎掃碼關注微信公眾號:「申城異鄉人」,不定期分享Java技術乾貨,讓我們一起進步。