本篇博客主要讲解鉴别器映射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. Win10《芒果TV - Preview》更新v3.1.31.0,全新播放页蜕变,预加载提速技术

    Win10<芒果TV - Preview>(商店内测版) v3.1.31.0 于2016年11月21日星期一晚上九点半登陆商店 主要是全面升级改造桌面播放页,新增观看互动评论.猜你喜欢功能 ...

  2. UWP入门(四)--设置控件样式

    原文:UWP入门(四)--设置控件样式 官方定义:可以使用 XAML 框架通过多种方式自定义应用的外观. 通过样式可以设置控件属性,并重复使用这些设置,以便保持多个控件具有一致的外观. 可分享至不同e ...

  3. Windows Azure之Mobile Service

    我建个android app和Windows Azure的Mobile Service配合,以实现会员注册的功能,实际十分简单,微软家的东西真心好用 首先新建个Mobile Service New-& ...

  4. 遗漏的SQL语句

    一.简单查询 1.限制返回行数 使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是表示一百分数,指定返回的行数等于总行数的百分之 ...

  5. Redis EXISTS命令耗时过长case排查

    一.背景 redis慢日志分析平台上线后,随便看了一下,发现onestore使用的缓存集群,存在大量的EXISTS命令慢查询的情况: 平均每个EXISTS命令需要13ms,最大耗时近20ms.这个结果 ...

  6. Python基础(七) 闭包与装饰器

    闭包的定义 闭包是嵌套在函数中的函数. 闭包必须是内层函数对外层函数的变量(非全局变量)的引用. 闭包格式: def func(): lst=[] def inner(a): lst.append(a ...

  7. 前端学习之Bootstrap学习

    一,Bootstrap简介 在前端世界,有个叫Bootstrap的家伙,,是twitter 开源出来的一套前端框架,利用Ta可以快速开发网站界面,它的特点就是比自己从头写简单,直观,方便,快捷,省劲. ...

  8. 修改linux(kali)和windows双系统下默认启动系统和启动延时

    我的公众号,正在建设中,欢迎关注: windows和kali双系统安装完成后kali是默认的启动系统,现将windows设置为默认启动系统并更改选择系统等待时间 1.开机时当运行到系统选择菜单时记下w ...

  9. Android开发需要了解的 IM 知识

    引言 即便在通讯如此发达的今天,IM 也依然是诸多场景下非常重要的基础能力.因此做为 一名 Android 开发,不可避免的会遇到一些IM 相关的需求或问题.本文以一个Android开发的角度来讲述I ...

  10. 【转载】java8中的Calendar日期对象(LocalDateTime)

    Java 8 推出了全新的日期时间API,Java 8 下的 java.time包下的所有类都是不可变类型而且线程安全. 下面是新版API中java.time包里的一些关键类: Instant:瞬时实 ...