MyBatis從入門到精通(十三):使用discriminator鑑別器映射

最近在讀劉增輝老師所著的《MyBatis從入門到精通》一書,頗有收穫,因而將本身學習的過程以博客形式輸出,若有錯誤,歡迎指正,如幫助到你,不勝榮幸!java

本篇博客主要講解鑑別器映射discriminator標籤的簡單用法。git

1. 明確需求

在設計之初,sys_role表的enabled字段有2個可選值,其中1表明啓用,0 表明禁用,當狀態啓用時就有對應的權限信息,當狀態禁用時就沒有對應的權限信息,只需查詢出角色信息便可。github

因此咱們的需求爲:根據用戶id查詢用戶擁有的角色列表,若是角色是啓用的,就繼續查詢出角色對應的權限列表,若是角色是禁用的,就不須要查詢對應的權限列表。sql

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映射,由於接下來會用到:mybatis

<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和對應的查詢語句:app

<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. 源碼及參考

源碼地址:github.com/zwwhnly/myb…,歡迎下載。

劉增輝《MyBatis從入門到精通》

5. 最後

打個小廣告,歡迎掃碼關注微信公衆號:「申城異鄉人」,按期分享Java技術乾貨,讓咱們一塊兒進步。

相關文章
相關標籤/搜索