main方法 如何去掉http debug日志_在MyBatis中如何使用collection标签实现嵌套查询?...

# 需求升级

在上篇博客《一对多的关系,在MyBatis中如何映射?》中,我们实现了需求:根据用户id查询用户信息的同时获取用户拥有的角色。

因为角色可以拥有多个权限,所以本篇博客我们升级需求为:根据用户id查询用户信息的同时获取用户拥有的角色以及角色包含的权限。

# 实现方式

因为我们需要使用到权限表的映射,所以我们需要先在SysPrivilegeMapper.xml中添加如下映射:

<resultMap id="sysPrivilegeMap" type="com.zwwhnly.mybatisaction.model.SysPrivilege">    <id property="id" column="id"/>    <result property="privilegeName" column="privilege_name"/>    <result property="privilegeUrl" column="privilege_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 id="rolePrivilegeListMap" extends="roleMap"           type="com.zwwhnly.mybatisaction.model.SysRoleExtend">    <collection property="sysPrivilegeList" columnPrefix="privilege_"                resultMap="com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap"/>resultMap>

这里的roleMap我们在之前的博客中已经定义过,代码如下:

<resultMap id="roleMap" type="com.zwwhnly.mybatisaction.model.SysRole">    <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>

com.zwwhnly.mybatisaction.mapper.SysPrivilegeMapper.sysPrivilegeMap就是我们刚刚在SysPrivilegeMapper.xml中新建的映射sysPrivilegeMap。

然后,需要将上篇博客中的userRoleListMap修改为:

<resultMap id="userRoleListMap" type="com.zwwhnly.mybatisaction.model.SysUserExtend" extends="sysUserMap">    <collection property="sysRoleList" columnPrefix="role_"                resultMap="com.zwwhnly.mybatisaction.mapper.SysRoleMapper.rolePrivilegeListMap">    collection>resultMap>

并且要修改上篇博客中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, admin@mybatis.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, admin@mybatis.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, admin@mybatis.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, admin@mybatis.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, admin@mybatis.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, test@mybatis.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, test@mybatis.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 id="selectPrivilegeByRoleId" resultMap="sysPrivilegeMap">    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 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><select id="selectRoleByUserId" resultMap="rolePrivilegeListMapSelect">    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="{roleId=id}"中,roleId指的是select指定的方法selectPrivilegeByRoleId的参数,id指的是查询selectRoleByUserId中查询出的角色id。

然后在SysUserMapper.xml中添加如下查询:

<resultMap id="userRoleListMapSelect" extends="sysUserMap"           type="com.zwwhnly.mybatisaction.model.SysUserExtend">    <collection property="sysRoleList" fetchType="lazy"                select="com.zwwhnly.mybatisaction.mapper.SysRoleMapper.selectRoleByUserId"                column="{userId=id}"/>resultMap>
<select id="selectAllUserAndRolesSelect" resultMap="userRoleListMapSelect">    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="{userId=id}"中,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, admin@mybatis.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 name="aggressiveLazyLoading" value="false"/>settings>

关于该参数的详细讲解,请查看MyBatis从入门到精通(十):使用association标签实现嵌套查询。

# 总结

使用collection标签实现嵌套查询,用到的属性总结如下:

1)select:另一个映射查询的id,MyBatis会额外执行这个查询获取嵌套对象的结果。

2)column:将主查询中列的结果作为嵌套查询的参数,配置方式如column="{prop1=col1,prop2=col2}",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万,就是真牛逼!
  • 如何在面试中介绍自己的项目经验?
  • 百度面试官:如果叫你设计一个短链接系统,你会从那些方面来提高性能呢?

6db08e30888e6dcd39e4c0ed864b7e15.png

790042521d84f6f22f62452c1c80d153.gif

点击

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/504052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

movielens推荐系统_案例|推荐系统的评估指标

推荐系统能够为用户提供个性化体验&#xff0c;现在基本上各大电商平台、资讯平台都会用推荐系统为自家评价下的用户提供千人千面的服务。平均精度均值&#xff08;Mean Average Precision&#xff0c;MAP&#xff09;便是评估推荐系统性能的度量标准之一。但是&#xff0c;使用…

mysql群集配置_CentOS7 - 建立一个MySQL集群

Standing up a MySQL cluster此配方将指导您完成设置MySQL群集的过程。 通过跨多个系统划分数据并维护副本以避免单点故障&#xff0c;群集数据库可以应对可伸缩性和高可用性的挑战。集群的成员称为节点。 MySQL集群中有三种节点类型&#xff1a;数据节点&#xff0c;API节点和…

叮!您收到一份超值Java基础入门资料!

Java语言有什么特点&#xff1f;如何最大效率的学习&#xff1f;深浅拷贝到底有何区别&#xff1f;阿里巴巴高级开发工程师为大家带来Java系统解读&#xff0c;带你掌握Java技术要领&#xff0c;突破重点难点&#xff0c;入门面向对象编程&#xff0c;以详细示例带领大家Java基…

jop怎么读音英语怎么说_“春晚”英语怎么说?

大家都说近年来的春节年味越来越淡&#xff0c;每年陪老人一起看春晚、上网吐槽春晚&#xff0c;应该算是最有年味的一件事了吧&#xff01;你期待今年的春晚吗&#xff1f;在春晚即将开播之际&#xff0c;先和我一起了解一些有关“春晚”的英语知识吧&#xff01;01、“春晚”…

2019 年软件开发人员必学的编程语言 Top 3

这篇文章将探讨编程语言世界的现在和未来&#xff0c;这些语言让新一代软件开发者成为这个数字世界的关键参与者&#xff0c;他们让这个世界变得更健壮、连接更加紧密和更有意义。开发者要想在 2019 年脱颖而出&#xff0c;这三门语言一定要关注。 作为软件开发者&#xff0c;…

小数据量计算最大lyapunov代码_Software | 计算Lyapunov指数的GUI工具箱及函数包汇总...

二十年前读书时用过的Lyapunov Exponents Toolbox&#xff0c;推荐给做非线性动力学入门的同学们。那个时候不会编写程序&#xff0c;做分支图、算连续或者离散系统的Lyapunov指数&#xff0c;极其困难&#xff0c;还好有这个工具箱&#xff0c;慢慢看源程序学会写一点改进的程…

git 小乌龟 更新分支_git常用操作

Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;它采用了分布式版本库的方式&a…

web 服务器 内存 影响_C/C++服务器开发常用的7大开源库,让你在同行中脱颖而出...

C/C服务器开发7大常用开源库&#xff0c;在这里简单介绍一下。1、OpenSSLOpenSSL是一个开放源代码的安全套接字层密码软件库&#xff0c;囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议&#xff0c;应用程序可以使用这个包来进行安全通信&#xff0c;避免窃听&…

pandas 更改单元格的值_懂Excel轻松入门Python数据分析包pandas(二十四):连续区域...

此系列文章收录在公众号中&#xff1a;数据大宇宙 > 数据处理 >E-pd转发本文并私信我"python"&#xff0c;即可获得Python资料以及更多系列文章(持续更新的)经常听别人说 Python 在数据领域有多厉害&#xff0c;结果学了很长时间&#xff0c;连数据处理都麻烦得…

产生式是蕴含式_独栋别墅~下沉式庭院设计

遇见美. 发现美创造美. 成就美有趣、有情奢享生活.创艺空间设计项目概述&#xff1a;这是一套婚房&#xff0c;从设计到装修完毕&#xff0c;历经三年。这是一生幸福开启的地方。一层为会客厅、室内花园、餐厅、茶室、老人房。原始房屋整体空间不够方正&#xff0c;空间利用率低…

在前端中如何在表格中最后一行加入输入框_UI设计进阶干货 — 如何制定UI规范...

APP为何要制定设计规范作为UI设计师&#xff0c;整理设计规范也是设计能力的一种体现。但很多小公司的设计师都觉得, 整个公司只有自己一个设计师, 所有的设计稿都是自己一个人做的, 风格肯定都是统一的, 所以没必要花那么长时间去做一个没有用的东西。但其实规范的本身并不是只…

如何用三元组表表示下列稀疏矩阵_盘一盘 Python 系列特别篇21之:SciPy 稀疏矩阵...

引言和稠密矩阵相比&#xff0c;稀疏矩阵的最大好处就是节省大量的内存空间来储存零。稀疏矩阵本质上还是矩阵&#xff0c;只不过多数位置是空的&#xff0c;那么存储所有的 0 非常浪费。稀疏矩阵的存储机制有很多种 (列出常用的五种)&#xff1a;COO (Coordinate List Format)…

六西格玛dfss_向六西格玛质量水平进攻!

为提高设计质量&#xff0c;提升研发团队整体作战能力&#xff0c;2019年初&#xff0c;技术中心确定了大力推进先进质量管理方法DFSS(六西格玛设计)的工作目标。一年来&#xff0c;在DFSS小组的策划组织和通用黑带大师的倾力支持下 &#xff0c;技术中心各区域工程师积极地学习…

c字符串中包含双引号_必须知道的C语言知识细节:单引号和双引号正确用法

C语言中ACSII码字符单引号和双引号"在程序中经常出现&#xff0c;很简单&#xff0c;但却是十分重要的语法标点符号&#xff0c;初学者容易混淆使用。单引号在字符常量时使用&#xff0c;表示单个字符。例如&#xff1a;char c;c a;c 1;c A;当在单引号中出现两个及以上…

计算机组成原理哈工大期末_浅谈计算机组成原理(三)

1、第二章&#xff1a;存储系统通过下面的思维导图来依次分享「存储系统」里面重要知识点。2、第一节&#xff1a;存储器的结构1. 主存储器&#xff1a;简称主存&#xff0c;又称内存储器(内存)&#xff0c;用来存放计算机运行期间所需的大量程序和数据&#xff0c;CPU可以直接…

网页中竖的目录怎么改成横的_怎么学习手绘插画?小白也能入门哦

怎么学习手绘插画&#xff1f;小白也能入门哦&#xff01;在回答这个问题之前&#xff0c;我们先来认识一下什么插画&#xff1f;相信很多人对插画这个概念是很笼统的。插画在中国被人们俗称为插图。发展至今其应用范围很是广泛包括&#xff1b;出版物配图、卡通吉祥物、广告、…

python自动测试v_python下selenium自动化测试自我实践

周末实验自动化提交数据时&#xff0c;本来没打算写记录的&#xff0c;不过遇到一些问题&#xff0c;觉得可以提提。基本操作就不用写了&#xff0c;搜索过程中都发现了两个博客都出了seleniumpython的书&#xff0c;说明操作一搜一大把。 1. 等待页面加载完成 本来用的sleep()…

graphpad细胞增殖曲线_肿瘤干细胞?居然被这两个新加坡人轻松干掉了?

近日&#xff0c;著名医学期刊《自然•医学》上发表了一篇关于肿瘤干细胞的文章。来自新加坡的研究团队发现&#xff0c;人类非小细胞肺癌的肿瘤干细胞需要大量的蛋氨酸&#xff0c;以维持自身组蛋白的甲基化&#xff0c;这对于肿瘤干细胞的生长和致瘤作用至关重要。同时&#…

isight参数优化理论与实例详解_案例1(ISIGHT集成ADAMS CAR方法实现)

本文字数1304字25图&#xff0c;建议阅读时间7分钟强调一下是ISIGHT&#xff0c;不是INSIGHTINSIGHT是ADAMS内置的一个试验设计模块&#xff0c;它提供了一组统计工具&#xff0c;用于分析仿真结果&#xff0c;辅助优化和改进系统ISIGHT是功能强大的计算机辅助优化平台&#xf…

修改图片src_【学习园地】企业SRC搭建

xSRC-企业SRC搭建腾讯xSRC 开源版是腾讯安全应急响应中心(TSRC)面向合作伙伴推出的安全应急响应中心(SRC)建站软件&#xff0c;软件源代码开放&#xff0c;可支持合作伙伴轻松构建SRC平台&#xff0c;省去大量开发运维工作&#xff0c;并支持个性化功能及页面设置&#xff0c;企…