MyBatis从入门到精通(十三):使用discriminator鉴别器映射
本篇博客主要讲解鉴别器映射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鉴别器映射的更多相关文章
- MyBatis从入门到精通(一):MyBatis入门
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. MyBatis简介 2001 ...
- MyBatis从入门到精通(二):MyBatis XML方式的基本用法之Select
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 明确需求 书中提到的需求是一个基 ...
- MyBatis从入门到精通(三):MyBatis XML方式的基本用法之多表查询
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 多表查询 上篇博客中,我们示例的 ...
- MyBatis从入门到精通(四):MyBatis XML方式的基本用法之增删改
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. insert用法 1.1 简单的 ...
- MyBatis从入门到精通(五):MyBatis 注解方式的基本用法
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. @Select 注解 1.1 使 ...
- MyBatis从入门到精通(六):MyBatis动态Sql之if标签的用法
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用if标签生成动 ...
- MyBatis从入门到精通(七):MyBatis动态Sql之choose,where,set标签的用法
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用choose, ...
- MyBatis从入门到精通(八):MyBatis动态Sql之foreach标签的用法
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用foreach ...
- MyBatis从入门到精通(九):MyBatis高级结果映射之一对一映射
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解MyBatis中实现查 ...
随机推荐
- Win10《芒果TV - Preview》更新v3.1.31.0,全新播放页蜕变,预加载提速技术
Win10<芒果TV - Preview>(商店内测版) v3.1.31.0 于2016年11月21日星期一晚上九点半登陆商店 主要是全面升级改造桌面播放页,新增观看互动评论.猜你喜欢功能 ...
- UWP入门(四)--设置控件样式
原文:UWP入门(四)--设置控件样式 官方定义:可以使用 XAML 框架通过多种方式自定义应用的外观. 通过样式可以设置控件属性,并重复使用这些设置,以便保持多个控件具有一致的外观. 可分享至不同e ...
- Windows Azure之Mobile Service
我建个android app和Windows Azure的Mobile Service配合,以实现会员注册的功能,实际十分简单,微软家的东西真心好用 首先新建个Mobile Service New-& ...
- 遗漏的SQL语句
一.简单查询 1.限制返回行数 使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是表示一百分数,指定返回的行数等于总行数的百分之 ...
- Redis EXISTS命令耗时过长case排查
一.背景 redis慢日志分析平台上线后,随便看了一下,发现onestore使用的缓存集群,存在大量的EXISTS命令慢查询的情况: 平均每个EXISTS命令需要13ms,最大耗时近20ms.这个结果 ...
- Python基础(七) 闭包与装饰器
闭包的定义 闭包是嵌套在函数中的函数. 闭包必须是内层函数对外层函数的变量(非全局变量)的引用. 闭包格式: def func(): lst=[] def inner(a): lst.append(a ...
- 前端学习之Bootstrap学习
一,Bootstrap简介 在前端世界,有个叫Bootstrap的家伙,,是twitter 开源出来的一套前端框架,利用Ta可以快速开发网站界面,它的特点就是比自己从头写简单,直观,方便,快捷,省劲. ...
- 修改linux(kali)和windows双系统下默认启动系统和启动延时
我的公众号,正在建设中,欢迎关注: windows和kali双系统安装完成后kali是默认的启动系统,现将windows设置为默认启动系统并更改选择系统等待时间 1.开机时当运行到系统选择菜单时记下w ...
- Android开发需要了解的 IM 知识
引言 即便在通讯如此发达的今天,IM 也依然是诸多场景下非常重要的基础能力.因此做为 一名 Android 开发,不可避免的会遇到一些IM 相关的需求或问题.本文以一个Android开发的角度来讲述I ...
- 【转载】java8中的Calendar日期对象(LocalDateTime)
Java 8 推出了全新的日期时间API,Java 8 下的 java.time包下的所有类都是不可变类型而且线程安全. 下面是新版API中java.time包里的一些关键类: Instant:瞬时实 ...