济南网站建设方案报价,新浪舆情系统,个人备案挂企业网站,社区网站如何做# 需求升级在上篇博客《一对多的关系#xff0c;在MyBatis中如何映射#xff1f;》中#xff0c;我们实现了需求#xff1a;根据用户id查询用户信息的同时获取用户拥有的角色。因为角色可以拥有多个权限#xff0c;所以本篇博客我们升级需求为#xff1a;根据用户id查询用… # 需求升级在上篇博客《一对多的关系在MyBatis中如何映射》中我们实现了需求根据用户id查询用户信息的同时获取用户拥有的角色。因为角色可以拥有多个权限所以本篇博客我们升级需求为根据用户id查询用户信息的同时获取用户拥有的角色以及角色包含的权限。# 实现方式因为我们需要使用到权限表的映射所以我们需要先在SysPrivilegeMapper.xml中添加如下映射resultMap idsysPrivilegeMap typecom.zwwhnly.mybatisaction.model.SysPrivilege id propertyid columnid/ result propertyprivilegeName columnprivilege_name/ result propertyprivilegeUrl columnprivilege_url/resultMap一般情况下不建议修改数据库表对应的实体类所以这里我们新建类SysRoleExtend让它继承SysRole类并添加如下字段package com.zwwhnly.mybatisaction.model;import java.util.List;public class SysRoleExtend extends SysRole { /** * 角色包含的权限列表 */ private List sysPrivilegeList; public ListgetSysPrivilegeList() { return sysPrivilegeList; } public void setSysPrivilegeList(List sysPrivilegeList) { this.sysPrivilegeList sysPrivilegeList; }}然后在SysRoleMapper.xml中新建如下映射resultMap idrolePrivilegeListMap extendsroleMap typecom.zwwhnly.mybatisaction.model.SysRoleExtend collection propertysysPrivilegeList columnPrefixprivilege_ resultMapcom.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap/resultMap这里的roleMap我们在之前的博客中已经定义过代码如下resultMap idroleMap typecom.zwwhnly.mybatisaction.model.SysRole id propertyid columnid/ result propertyroleName columnrole_name/ result propertyenabled columnenabled/ result propertycreateBy columncreate_by/ result propertycreateTime columncreate_time jdbcTypeTIMESTAMP/resultMapcom.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap就是我们刚刚在SysPrivilegeMapper.xml中新建的映射sysPrivilegeMap。然后需要将上篇博客中的userRoleListMap修改为resultMap iduserRoleListMap typecom.zwwhnly.mybatisaction.model.SysUserExtend extendssysUserMap collection propertysysRoleList columnPrefixrole_ resultMapcom.zwwhnly.mybatisaction.mapper.SysRoleMapper.rolePrivilegeListMap collectionresultMap并且要修改上篇博客中id为selectAllUserAndRoles的select标签代码因为要关联角色权限关系表和权限表 SELECT u.id, u.user_name, u.user_password, u.user_email, u.create_time, r.id role_id, r.role_name role_role_name, r.enabled role_enabled, r.create_by role_create_by, r.create_time role_create_time, p.id role_privilege_id, p.privilege_name role_privilege_privilege_name, p.privilege_url role_privilege_privilege_url FROM sys_user u INNER JOIN sys_user_role ur ON u.id ur.user_id INNER JOIN sys_role r ON ur.role_id r.id INNER JOIN sys_role_privilege rp ON rp.role_id r.id INNER JOIN sys_privilege p ON p.id rp.privilege_id注意事项这里sys_privilege表的列名的别名前缀为role_privilege_这是因为userRoleListMap中collection的columnPrefix属性为role_并且指定的com.zwwhnly.mybatisaction.mapper.SysRoleMapper.rolePrivilegeListMap中collection的columnPrefix属性为privilege_所以这里的前缀需要叠加就变成了role_privilege_。# 单元测试修改上篇博客中建的测试方法testSelectAllUserAndRoles()代码为Testpublic void testSelectAllUserAndRoles() { SqlSession sqlSession getSqlSession(); try { SysUserMapper sysUserMapper sqlSession.getMapper(SysUserMapper.class); List sysUserList sysUserMapper.selectAllUserAndRoles(); System.out.println(用户数 sysUserList.size()); for (SysUserExtend sysUser : sysUserList) { System.out.println(用户名 sysUser.getUserName()); for (SysRoleExtend sysRoleExtend : sysUser.getSysRoleList()) { System.out.println(角色名 sysRoleExtend.getRoleName()); for (SysPrivilege sysPrivilege : sysRoleExtend.getSysPrivilegeList()) { System.out.println(权限名 sysPrivilege.getPrivilegeName()); } } } } finally { sqlSession.close(); }}运行测试代码测试通过输出日志如下DEBUG [main] - Preparing: SELECT u.id, u.user_name, u.user_password, u.user_email, u.create_time, r.id role_id, r.role_name role_role_name, r.enabled role_enabled, r.create_by role_create_by, r.create_time role_create_time, p.id role_privilege_id, p.privilege_name role_privilege_privilege_name, p.privilege_url role_privilege_privilege_url FROM sys_user u INNER JOIN sys_user_role ur ON u.id ur.user_id INNER JOIN sys_role r ON ur.role_id r.id INNER JOIN sys_role_privilege rp ON rp.role_id r.id INNER JOIN sys_privilege p ON p.id rp.privilege_idDEBUG [main] - Parameters:TRACE [main] - Columns: id, user_name, user_password, user_email, create_time, role_id, role_role_name, role_enabled, role_create_by, role_create_time, role_privilege_id, role_privilege_privilege_name, role_privilege_privilege_urlTRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0, 1, 管理员, 1, 1, 2019-06-27 18:21:12.0, 1, 用户管理, /usersTRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0, 1, 管理员, 1, 1, 2019-06-27 18:21:12.0, 2, 角色管理, /rolesTRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0, 1, 管理员, 1, 1, 2019-06-27 18:21:12.0, 3, 系统日志, /logsTRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用户, 1, 1, 2019-06-27 18:21:12.0, 4, 人员维护, /personsTRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用户, 1, 1, 2019-06-27 18:21:12.0, 5, 单位维护, /companiesTRACE [main] - Row: 1001, test, 123456, testmybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用户, 1, 1, 2019-06-27 18:21:12.0, 4, 人员维护, /personsTRACE [main] - Row: 1001, test, 123456, testmybatis.tk, 2019-06-27 18:21:07.0, 2, 普通用户, 1, 1, 2019-06-27 18:21:12.0, 5, 单位维护, /companiesDEBUG [main] - Total: 7用户数2用户名admin角色名管理员权限名用户管理权限名角色管理权限名系统日志角色名普通用户权限名人员维护权限名单位维护用户名test角色名普通用户权限名人员维护权限名单位维护从日志可以看出不仅查询出了用户拥有的角色信息也查询出了角色包含的权限信息。# 延迟加载有的同学可能会说返回的角色信息和权限信息我不一定用啊每次关联这么多表查询一次数据库好影响性能啊能不能在我使用到角色信息即获取sysRoleList属性时再去数据库查询呢答案当然是能那么如何实现呢实现延迟加载需要使用collection标签的fetchType属性该属性有lazy和eager两个值分别代表延迟加载和积极加载。由于需要根据角色Id获取该角色对应的所有权限信息所以我们要先在SysPrivilegeMapper.xml中定义如下查询select idselectPrivilegeByRoleId resultMapsysPrivilegeMap SELECT p.* FROM sys_privilege p INNER JOIN sys_role_privilege rp ON rp.privilege_id p.id WHERE rp.role_id #{roleId}select然后在SysRoleMapper.xml中添加如下查询resultMap idrolePrivilegeListMapSelect extendsroleMap typecom.zwwhnly.mybatisaction.model.SysRoleExtend collection propertysysPrivilegeList fetchTypelazy column{roleIdid} selectcom.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.selectPrivilegeByRoleId/resultMapselect idselectRoleByUserId resultMaprolePrivilegeListMapSelect 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上面的column{roleIdid}中roleId指的是select指定的方法selectPrivilegeByRoleId的参数id指的是查询selectRoleByUserId中查询出的角色id。然后在SysUserMapper.xml中添加如下查询resultMap iduserRoleListMapSelect extendssysUserMap typecom.zwwhnly.mybatisaction.model.SysUserExtend collection propertysysRoleList fetchTypelazy selectcom.zwwhnly.mybatisaction.mapper.SysRoleMapper.selectRoleByUserId column{userIdid}/resultMapselect idselectAllUserAndRolesSelect resultMapuserRoleListMapSelect SELECT u.id, u.user_name, u.user_password, u.user_email, u.create_time FROM sys_user u WHERE u.id #{id}select上面的column{userIdid}中userId指的是select指定的方法selectRoleByUserId的参数id指的是查询selectAllUserAndRolesSelect中查询出的用户id。然后在SysUserMapper接口中添加如下方法/** * 通过嵌套查询获取指定用户的信息以及用户的角色和权限信息 * * param id * return */SysUserExtend selectAllUserAndRolesSelect(Long id);最后在SysUserMapperTest类中添加如下测试方法Testpublic void testSelectAllUserAndRolesSelect() { SqlSession sqlSession getSqlSession(); try { SysUserMapper sysUserMapper sqlSession.getMapper(SysUserMapper.class); SysUserExtend sysUserExtend sysUserMapper.selectAllUserAndRolesSelect(1L); System.out.println(用户名 sysUserExtend.getUserName()); for (SysRoleExtend sysRoleExtend : sysUserExtend.getSysRoleList()) { System.out.println(角色名 sysRoleExtend.getRoleName()); for (SysPrivilege sysPrivilege : sysRoleExtend.getSysPrivilegeList()) { System.out.println(权限名 sysPrivilege.getPrivilegeName()); } } } finally { sqlSession.close(); }}运行测试方法输出日志如下DEBUG [main] - Preparing: SELECT u.id, u.user_name, u.user_password, u.user_email, u.create_time FROM sys_user u WHERE u.id ?DEBUG [main] - Parameters: 1(Long)TRACE [main] - Columns: id, user_name, user_password, user_email, create_timeTRACE [main] - Row: 1, admin, 123456, adminmybatis.tk, 2019-06-27 18:21:07.0DEBUG [main] - Total: 1用户名adminDEBUG [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_timeTRACE [main] - Row: 1, 管理员, 1, 1, 2019-06-27 18:21:12.0TRACE [main] - Row: 2, 普通用户, 1, 1, 2019-06-27 18:21:12.0DEBUG [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_urlTRACE [main] - Row: 1, 用户管理, /usersTRACE [main] - Row: 2, 角色管理, /rolesTRACE [main] - Row: 3, 系统日志, /logsDEBUG [main] - Total: 3权限名用户管理权限名角色管理权限名系统日志角色名普通用户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: 2(Long)TRACE [main] - Columns: id, privilege_name, privilege_urlTRACE [main] - Row: 4, 人员维护, /personsTRACE [main] - Row: 5, 单位维护, /companiesDEBUG [main] - Total: 2权限名人员维护权限名单位维护仔细分析上面的日志会发现只有在使用到了角色信息和权限信息时才执行了对应的数据库查询。需要注意的是延迟加载依赖于MyBatis全局配置中的aggressiveLazyLoading在之前的博客讲解association标签时我们已经将其配置为了false所以这里的执行结果符合我们的预期settings setting nameaggressiveLazyLoading valuefalse/settings关于该参数的详细讲解请查看MyBatis从入门到精通(十)使用association标签实现嵌套查询。# 总结使用collection标签实现嵌套查询用到的属性总结如下1)select另一个映射查询的idMyBatis会额外执行这个查询获取嵌套对象的结果。2)column将主查询中列的结果作为嵌套查询的参数配置方式如column{prop1col1,prop2col2},prop1和prop2将作为嵌套查询的参数。3)fetchType数据加载方式可选值为lazy和eager分别为延迟加载和积极加载。4)如果要使用延迟加载除了将fetchType设置为lazy还需要注意全局配置aggressiveLazyLoading的值应该为false。这个参数在3.4.5版本之前默认值为ture从3.4.5版本开始默认值改为false。5)MyBatis提供的lazyLoadTriggerMethods参数支持在触发某方法时直接触发延迟加载属性的查询如equals()方法。# 源码及参考源码地址https://github.com/zwwhnly/mybatis-action.git欢迎下载。刘增辉《MyBatis从入门到精通》作者申城异乡人来源https://www.cnblogs.com/zwwhnly/p/11201185.html 往期推荐 ?一个小需求能够做到月活跃用户5000万就是真牛逼如何在面试中介绍自己的项目经验百度面试官如果叫你设计一个短链接系统你会从那些方面来提高性能呢点击