本篇博客主要讲解鉴别器映射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从入门到精通》

原创不易,如果觉得文章能学到东西的话,欢迎点个赞、评个论、关个注,这是我坚持写作的最大动力。

如果有兴趣,欢迎添加我的微信:zwwhnly,等你来聊技术、职场、工作等话题(PS:我是一名奋斗在上海的程序员)。

MyBatis从入门到精通(十三):使用discriminator鉴别器映射的更多相关文章

  1. MyBatis从入门到精通(一):MyBatis入门

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. MyBatis简介 ​ 2001 ...

  2. MyBatis从入门到精通(二):MyBatis XML方式的基本用法之Select

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 明确需求 书中提到的需求是一个基 ...

  3. MyBatis从入门到精通(三):MyBatis XML方式的基本用法之多表查询

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 多表查询 上篇博客中,我们示例的 ...

  4. MyBatis从入门到精通(四):MyBatis XML方式的基本用法之增删改

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. insert用法 1.1 简单的 ...

  5. MyBatis从入门到精通(五):MyBatis 注解方式的基本用法

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. @Select 注解 1.1 使 ...

  6. MyBatis从入门到精通(六):MyBatis动态Sql之if标签的用法

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用if标签生成动 ...

  7. MyBatis从入门到精通(七):MyBatis动态Sql之choose,where,set标签的用法

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用choose, ...

  8. MyBatis从入门到精通(八):MyBatis动态Sql之foreach标签的用法

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用foreach ...

  9. MyBatis从入门到精通(九):MyBatis高级结果映射之一对一映射

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解MyBatis中实现查 ...

随机推荐

  1. 关于SetLocaleInfo()

    原文:关于SetLocaleInfo() 此函数用于设置系统的一些本地信息, 非常有用. 比如日期格式为'yyyy/mm/dd'时, 稍微不注意,有些程序语句会报错. 以下资料网络收集: 1. Set ...

  2. jquery-ui sortable 使用实例

    jquery-ui sortable 使用实例 最近公司需要做任务看板,需要拖拽效果.点击查看效果.由于网站是基于vue的技术栈,最开始找了一个现成的vue封装的拖拽组件:Vue.Draggable, ...

  3. 线程天敌TerminateThread与SuspendThread

    线程天敌TerminateThread与SuspendThread 作者:童磊(magictong) 目的:不是演示TerminateThread和SuspendThread的原理而是希望能在自己的程 ...

  4. SYN5006型电机同步编码脉冲分配器

    SYN5006型电机同步编码脉冲分配器 编码器信号分配板增量式编码器脉冲分配器使用说明视频链接: http://www.syn029.com/h-pd-81-0_310_13_-1.html 请将此链 ...

  5. 30411MySQL安装与配置_win10

    1 下载 1.1下载地址 下载地址  https://downloads.mysql.com/archives/community/ 1.2 选择适合自己的版本并下载 1.3 将下载文件解压至自定义路 ...

  6. Error: Cannot find module '@babel/runtime/core-js/object/keys'(npm start报错)

    1.问题描述: 在npm start启动react项目的时候,会出现Cannot find module '@babel/runtime/core-js/object/keys'的报错: 打开:项目根 ...

  7. 数据库读写分离Master-Slave

    数据库读写分离Master-Slave 一个平台或系统随着时间的推移和用户量的增多,数据库操作往往会变慢,这时我们需要一些有效的优化手段来提高数据库的执行速度:如SQL优化.表结构优化.索引优化.引擎 ...

  8. 浅谈ASP.NET Core中IOC与DI的理解和使用

    说起IOC和DI,使用过ASP.NET Core的人对这两个概念一定不陌生,早前,自己也有尝试过去了解这两个东西,但是一直觉得有点很难去理解,总觉得对其还是模糊不清,所以,趁着今天有空,就去把两个概念 ...

  9. ASP.NET MVC/Core表单提交后台模型二级属性验证问题

    起因 这个是网友在官网论坛的提问:https://fineui.com/bbs/forum.php?mod=viewthread&tid=22237 重新问题 本着务实求真的态度,我们先来复现 ...

  10. java的equals与==的区别

    看了网上关于equal与==的区别,感觉很多有些片面,不仔细,这里我来说说我对equal与==的理解 首先要了解基本类型与引用类型 1.int,char,boolean之类的就是基本类型,我们只要使用 ...