最近在读刘增辉老师所著的《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. 最后
来源: https://www.cnblogs.com/zwwhnly/p/11212396.html