日常开发中有这中场景,一个用户有多个角色,一个角色又有多个菜单,想查出一个用户的所有菜单。除了常见的关联查询之外,更使用的应该是利用myBatis的resultMap来实现一次查询出多个结果集,缺点:每次组装结果集实际上是重新调用一次连接池,查询大量的数据时会造成资源浪费和效率不高。

首先声明一个BaseresultMapDetail,对应的映射实体类为SysMember,整个resultMap类似这样:

<resultMap id="BaseResultMapDetail" type="com.wx.web.entity.sys.SysMember" >
<id column="id" property="id"/>
<result column="mem_name" property="memName"/>
<result column="mem_pwd" property="memPwd"/>
<result column="mem_qq" property="memQq"/>
<result column="mem_mobile" property="memMobile"/>
<result column="mem_email" property="memEmail"/>
<result column="mem_trueName" property="memTrueName"/>
<result column="mem_status" property="memStatus"/>
<result column="mem_validate_type" property="memValidateType"/>
<result column="mem_type" property="memType"/>
<result column="mem_invitation_code" property="memInvitationCode"/>
<result column="mem_invited_code" property="memInvitedCode"/>
<result column="mem_parent_id" property="memParentId"/>
<result column="item_id" property="itemId"/>
<result column="item_original" property="itemOriginal"/>
<result column="create_by" property="createBy"/>
<result column="create_date" property="createDate"/>
<result column="update_by" property="updateBy"/>
<result column="update_date" property="updateDate"/>
<result column="remarks" property="remarks"/>
<result column="del_flag" property="delFlag"/>
<association property="parentMember" column="mem_parent_id" select="selectParentMemberById"></association>
<collection property="roleList" column="id" ofType="com.wx.web.entity.sys.SysRole" select="selectRoleList"></collection>
<collection property="menuList" column="id" ofType="com.wx.web.entity.sys.SysMenu" select="selectMenuList"></collection>
<collection property="menuBtnList" column="id" ofType="com.wx.web.entity.sys.SysMenuBtn" select="selectMenuBtnList"></collection>

</resultMap>

如上所示,查询一条记录的是使用association,查询数据集合List的时候使用collection,property对应实体类中的属性,column为所对应的外键字段名称,ofType对应映射的实体类,select为另一个查询(一个单独的查询结果),形式如下:

<!-- 根据id查询角色列表 -->
<select id="selectParentMemberById" resultType="com.wx.web.entity.sys.SysMember" parameterType="java.lang.String">
SELECT
t.id AS id,
t.mem_name AS memName,
t.mem_mobile AS memMobile,
t.mem_type AS memType,
t.mem_invitation_code AS memInvitationCode,
t.mem_trueName AS memTrueName
FROM
tb_sys_member t
WHERE
t.id = #{id} and t.del_flag=0
</select> <!-- 根据id查询角色列表 -->
<select id="selectRoleList" resultType="com.wx.web.entity.sys.SysRole" parameterType="java.lang.String">
SELECT
t.id AS id,
t.role_code AS roleCode,
t.role_name AS roleName
FROM
tb_sys_role t
LEFT JOIN tb_sys_role_member t1 ON t.id = t1.role_id
WHERE
t1.member_id = #{id} and t.del_flag=0
</select> <!-- 根据id查询菜单列表 -->
<select id="selectMenuList" resultType="com.wx.web.entity.sys.SysMenu" parameterType="java.lang.String">
SELECT DISTINCT
t.id AS id,
t.menu_grade AS menuGrade,
t.menu_name AS menuName,
t.menu_url as menuUrl,
t.parent_menu_id as 'parentMenu.id',
t.create_date as createDate
FROM
tb_sys_menu t
LEFT JOIN tb_sys_role_menu t1 ON t.id = t1.menu_id
LEFT JOIN tb_sys_role_member t2 on t1.role_id = t2.role_id
WHERE
t2.member_id = #{id} and t.del_flag=0
order by t.create_date
</select> <!-- 根据id查询菜单按钮列表 -->
<select id="selectMenuBtnList" resultType="com.wx.web.entity.sys.SysMenuBtn" parameterType="java.lang.String">
SELECT DISTINCT
t.id AS id,
t.menu_id AS menuId,
t.btn_name AS btnName,
t.btn_permissions AS btnPermissions
FROM
tb_sys_menu_btn t
LEFT JOIN tb_sys_role_menu t1 ON t.id = t1.menu_id
LEFT JOIN tb_sys_role_member t2 on t1.role_id = t2.role_id
WHERE
t2.member_id = #{id} and t.del_flag=0
order by t.create_date
</select>

并且SysMember实体类中定义好相应的属性,并实现get/set方法:

private SysMember parentMember; // 上级用户实体类
private List<SysRole> roleList; // 拥有的角色
private List<SysMenu> menuList; // 拥有的菜单
private List<String> permissionsList; // 拥有的菜单权限
private List<SysMenuBtn> menuBtnList; // 拥有的菜单按钮

具体查询使用的时候,指定resultMap为事先声明的BaseresultMapDetail,

<!-- 根据id查询 会员 -->
<select id="queryById" resultMap="BaseResultMapDetail" parameterType="Object">
select <include refid="Base_Column_List" />
from tb_sys_member
where id = #{id} and del_flag=0
</select>

当执行queryById的时候,debug调试时可以发现除了执行queryById本身的sql之外,还执行了四次sql,分是selectParentMemberById、selectRoleList、selectMenuList、selectMenuBtnList对应的查询操作。执行后将这些查询结果全部映射到SysMember中的各个实体类属性。

myBatis的一对多查询,主要利用resultMap实现一次查询多个结果集的更多相关文章

  1. mybatis collection 一对多关联查询,单边分页的问题总结!

    若想直接通过sql实现多级关联查询表结构得有2 个必不可少的字段:id ,parentId,levelId id:主键id, parentId:父id levelId:表示第几级(表本身关联查询的时候 ...

  2. Mybatis学习——一对多关联表查询

    1.实体类 public class Student { private int id; private String name; } public class Classes { private i ...

  3. 19_高级映射:一对多查询(使用resultMap)

    [需求] 查询订单以及订单明细的信息. 确定主查询表:订单表orders 确定关联查询表:订单明细表 orderdetail 在一对一查询的基础上添加订单明细表关联即可. [分析] 使用resultM ...

  4. MyBatis:一对多关联查询

    MyBatis从入门到放弃四:一对多关联查询 前言 上篇学习了一对一关联查询,这篇我们学习一对多关联查询.一对多关联查询关键点则依然是配置resultMap,在resultMap中配置collecti ...

  5. java:Mybatis框架2(基于mapper接口的开发,多种查询,复合类型查询,resultMap定义,多表联查,sql片段)

    1.mybatis02: mybatis-config.xml: <?xml version="1.0" encoding="UTF-8"?> &l ...

  6. mybatis中一对多查询collection关联不执行

    今天遇到的原因是因为下面红底id没有,导致关联查询没有条件(id字段没传),所以一直没有执行. <?xml version="1.0" encoding="UTF- ...

  7. mybatis 13: 一对多关联查询

    业务背景 根据客户id查询客户基本信息,以及客户存在的订单信息 两张数据表 客户表 订单表 实体类 客户实体类:Customer private Integer id; private String ...

  8. mybatis 一对多的注入 指的是连表查询时候 将不同的查询结果以列表存储对象形式 注入进去 多对一指的是 查询多条结果但都是一样的 只需注入一条

    mybatis 一对多的注入 指的是连表查询时候 将不同的查询结果以列表存储对象形式 注入进去 多对一指的是 查询多条结果但都是一样的 只需注入一条

  9. 好947 Mybatis 配置resultMap 带參数查询Map 注意selectOne数据库返回结果一条数据库 否则会报错

    //TMD 写几个demo 还有大站採集 <a target=_blank href="http://hao947.com/" target="_blank&quo ...

随机推荐

  1. setTimeout和setInterval的注意事项

    精准问题 setTimeout的问题在于它并不是精准的,例如使用setTimeout设定一个任务在10ms后执行,但是在9ms后,有一个任务占用了5ms的cpu时间片,再次轮到定时器执行时,时间已经过 ...

  2. git 教程(14)--解决冲突

    人生不如意之事十之八九,合并分支往往也不是一帆风顺的. 准备新的feature1分支,继续我们的新分支开发:

  3. Linux下对比两个文件夹的方法

    最近拿到一份源代码,要命的是这份源代码是浅克隆模式的git包,所以无法完整显示里面的修改的内容. 今天花了一点点时间,找了一个在Linux对比两个文件夹的方法. 其实方法很简单,用meld 去对比两个 ...

  4. 【转】ubuntu 配置 java jdk1.8 环境,增加多版本 jdk 和切换方法

    一.安装java jdk1.8 1.添加软件源 sudo add-apt-repository ppa:webupd8team/java 2.更新软件源 sudo apt-get update 3.安 ...

  5. 学习JVM GarbageCollection

    前言 Java和C++之间显著的一个区别就是对内存的管理.Java和C++把内存管理的权利赋予给开发人员的方式不同,Java拥有一套自动的内存回收系统(Garbage Collection,GC)简称 ...

  6. Servlet 之 HttpServlet

    package cn.jiemoxiaodi.http; import java.io.IOException; import javax.servlet.GenericServlet; import ...

  7. nginx笔记资料

    通配 hash 表 ngx_hash_init 实现注释:http://blog.csdn.net/gsnumen/article/details/7817396 ngx_hash_init之后的结构 ...

  8. CSS3 外发光 渐变色

    渐变色--线性渐变 linear-gradient #bg { width: 100%; background: -webkit-linear-gradient(#9f1c65, #d89068,#7 ...

  9. MediaElement.js之浏览器跨域请求视频播放

    浏览器跨域问题一直以来都是作为前端开发人员常见的问题,所以今天学习了下如何使浏览器跨域请求资源 需要了解的知识 -域(主域,子域,什么是跨域) 简单来说由于浏览器同源策略,凡是发送请求url的协议(h ...

  10. 激活webstorm2016如何激活webstorm2016永久激活webstorm2016

    没有那么麻烦,我这个方法是简单粗暴: 1.搜webstrom2016,最新的是2016.3 2.官方下载 3.断网,改本地时间,你打算用多久,就把本地时间往未来调多久 4.安装webstorm 5.一 ...