mybatis 查询优化主子表查询之association和collection
很多开发人员之所以编写出低效的应用,有一大原因是并不理解怎样编写高效的SQL。以订单查询为例,我们经常需要查询某个用户的订单以及订单明细,并且以树形方式展现如下:

对于这种性质的功能,很多开发人员的做法是先查询主表,然后根据主表去循环子表,如下所示:
List<Department> depts = DepartmentMapper.queryDept();
for (Department dept: depts) {
dept.setEmps(EmployeeMapper.queryEmp(dept.id));
}
这种做法就是典型的过程性编程思维,它不仅在更改查询条件或字段时维护性差、不支持两个表的查询条件,而且性能低下,主表有几条记录就会导致请求数据库几次,不仅应用响应时间长,服务器也耗费了更多的资源。更好的做法是一次性查询会所有符合条件的记录,然后再应用中进行拆分并组装,主流的ORM框架几乎都支持这些模式,以使用最广泛的Mybatis为例,其结果映射resultMap中的association(用于一对一和多对一)和collection(用于一对多)元素支持自动将二位结果映射为主子对象。如下所示:
<mapper namespace="chapter6.dao.DepartmentMapper">
<!-- 嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则 -->
<resultMap type="chapter6.Department" id="MyDept">
<id column="did" property="id"/>
<result column="dept_name" property="departmentName"/>
<collection property="emps" ofType="chapter6.Employee">
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
</resultMap> <select id="queryDept" resultMap="MyDept" >
SELECT
d.id did,
d.dept_name dept_name,
e.id,
e.last_name last_name,
e.email email,
e.gender gender
FROM
tbl_dept d
LEFT JOIN tbl_employee e ON d.id = e.d_id
</select>
</mapper>
association同样可以实现相同功能,不过明细表是主表,如下所示:
<mapper namespace="com.abc.mapper.StudentMapper">
<select id="getById" parameterType="int"
resultMap="studentResultMap">
select s.id s_id,
s.name s_name,
s.gender s_gender,
s.major s_major,
s.grade s_grade,
t.id t_id,
t.name t_name,
t.gender t_gender,
t.title t_title,
t.research_area t_research_area
from student s left join teacher t
on s.supervisor_id = t.id
where s.id=#{id}
</select>
<resultMap id="studentResultMap" type="Student">
<id property="id" column="s_id" />
<result property="name" column="s_name" />
<result property="gender" column="s_gender" />
<result property="major" column="s_major" />
<result property="grade" column="s_grade" />
<!--使用resultMap属性引用下面的教师实体映射 -->
<association property="supervisor" javaType="Teacher"
resultMap="supervisorResultMap" />
</resultMap>
<!--教师实体映射 -->
<resultMap id="supervisorResultMap" type="Teacher">
<id property="id" column="t_id" />
<result property="name" column="t_name" />
<result property="gender" column="t_gender" />
<result property="researchArea" column="t_research_area" />
<result property="title" column="t_title" />
</resultMap>
</mapper>
需要注意的是,默认情况下Mapper中使用association标签,select 有大量相同的数据,此时会出现问题, 有的数据可以联查出来, 而有的不可以。此时需要开启缓存开关,参考https://blog.csdn.net/qq_27848369/article/details/80534253
mybatis 查询优化主子表查询之association和collection的更多相关文章
- MyBatis的多表查询笔记
MyBatis的多表查询 随着学习的进步,需求的提高,我们在实际开发中用的最多的还是多表查询,就让我们一起学习MyBatis中的多表查询. 数据库准备 Class表 Student表 项目结构 这次使 ...
- 使用Mybatis进行连表查询、left join---https://blog.csdn.net/jinzhencs/article/details/51980518
使用Mybatis进行连表查询.left join https://blog.csdn.net/jinzhencs/article/details/51980518
- SpringBoot集成Mybatis实现多表查询的两种方式(基于xml)
下面将在用户和账户进行一对一查询的基础上进行介绍SpringBoot集成Mybatis实现多表查询的基于xml的两种方式. 首先我们先创建两个数据库表,分别是user用户表和account账户表 ...
- MyBatis实现关联表查询
一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...
- MyBatis——实现关联表查询
原文:http://www.cnblogs.com/xdp-gacl/p/4264440.html 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创 ...
- Mybatis系列(三):Mybatis实现关联表查询
原文链接:http://www.cnblogs.com/xdp-gacl/p/4264440.html 一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 ...
- MyBatis—实现关联表查询
一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...
- 07 Mybatis的多表查询1----1对多和多对1---@Results注解用法总结
1.表与表之间的关系及其举例 表之间的关系有4种:一对多.多对一.一对一.多对多. 举例: (1)用户和订单就是一对多 一个用户可以下多个订单 (2)订单和用户就是多对一 多个订单属于同一个用户 (3 ...
- MyBatis框架——多表查询
MyBatis多表查询, 从表中映射主表,使用 association 标签,通过设置 javaType 属性关联实体类: 主表映射从表,使用 collection 标签,通过 ofType 属性关联 ...
随机推荐
- 11.17 luffycity(7)完结
2018-11-17 15:59:01 路飞项目已经完结!后面已是flask的学习!然后还有十几天的课程等回学校再看 明天归校!! 开始全面整理自己学习的知识,整理博客!还有好多面试题!233333 ...
- lxml xpath 爬取并正常显示中文内容
在使用python爬虫提取中文网页的内容,为了能正确显示中文的内容,在转为字符串时一定要声明编码为utf-8,否则无法正常显示中文,而是显示原编码的字符,并没有正确转换.比如下面这个简单的爬取百度页面 ...
- linux的基本操作(磁盘管理)
磁盘管理 [查看磁盘或者目录的容量 df 和 du] df 查看已挂载磁盘的总容量.使用容量.剩余容量等,可以不加任何参数,默认是按k为单位显示的 df常用参数有 –i -h -k –m等 -i 使用 ...
- vue中的图标字体引入
网址:https://icomoon.io/app/#/select: 特点:样式多,免费 操作: 1.相中的,随便点,不要钱,generat fonts然后download,得到一个压缩文件,解压, ...
- JavaScript 里,$ 代表什么?/JQuery是什么语言?/html中用link标签引入css时的中 rel="stylesheet"属性?/EL表达式是什么?
JavaScript 里,$ 代表什么? 比如说我写一个mouseover事件: $(document).ready(function(){ $("p").mouseover(fu ...
- mui 轮播
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- RDLC报表刷新问题
使用RDLC做报表,当数据源发生改变时重新绑定数据发现报表没有变化,跟踪时发现数据绑定已经正确执行,前端也显示了加载过程,但内容未刷新. 在代码中使用了 ReportViewer1.LocalRepo ...
- POJ 2187 - Beauty Contest - [凸包+旋转卡壳法][凸包的直径]
题目链接:http://poj.org/problem?id=2187 Time Limit: 3000MS Memory Limit: 65536K Description Bessie, Farm ...
- 线程安全 Thread Safety Problem scala concurrency 并发
小结: 1.基于java并发模型 Scala concurrency is built on top of the Java concurrency model. 2. 将每个请求放入一个新的线程 T ...
- python摸爬滚打之day20--多继承,MRO和C3算法
1.新式类和经典类 在python2.2之前, 基类如果不写(), 则表示为经典类; 在python2.2之后, 经典类不复存在, 只存在新式类. 如果基类谁都不继承的话, 则默认继承object. ...