MyBatis加强(1)~myBatis对象关系映射(多对一关系、一对多关系)、延迟/懒加载
一、myBatis对象关系映射(多对一关系、一对多关系)
1、多对一关系:
---例子:多个员工同属于一个部门。
(1)myBatis发送 额外SQL:
■ 案例:员工表通过 dept_id 关联 部门表,需求:查询指定员工id、name、所属的部门名称的信息。

//部门对象的接口、映射文件省略,跟员工逻辑差不多
/* 员工对象的接口 */
public interface EmployeeMapper {
Employee get(Long id);
}
<!--员工对象的映射文件-->
<!-- 解决列名和属性名不匹配问题 -->
<resultMap id="BaseResultMap" type="Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="dept_id" property="dept.id"/>
</resultMap>
<!-- 查询操作 -->
<select id="get" resultMap="BaseResultMap">
select id, name, dept_id from employee2 where id = #{id}
</select>
/* 测试:查询指定员工id、name、所属的部门名称的信息 */
@Test
public void testGet() throws Exception {
SqlSession session = MyBatisUtil.getSession();
EmployeeMapper employeeMapper = session.getMapper(EmployeeMapper.class);
Employee e = employeeMapper.get(1L);
System.out.println(e);
//需要通过查询得到的dept_id查询获取得到部门对象
/**
* 额外的查询语句,可以通过配置resultMap的association属性,让myBatis帮我们执行
*/
//手动添加额外查询语句
// Long dept_id = e.getDept().getId();
// DepartmentMapper departmentMapper = session.getMapper(DepartmentMapper.class);
// Department d = departmentMapper.get(dept_id);
// e.setDept(d);
System.out.println(e.getDept());
session.commit();
session.close();
}
上面是通过手动添加的额外SQL查询,通过配置resultMap的association属性,让myBatis帮我们执行如下:
<!-- 解决列名和属性名不匹配问题 -->
<resultMap id="BaseResultMap" type="Employee">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--<result column="dept_id" property="dept.id"/> -->
<!-- 额外的SQL配置方式
association元素:配置单一元素的关联关系
property 属性:对象的属性
select 属性:发送额外的sql
column 属性: 将指定的列的值传递给额外sql
-->
<association property="dept"
select="com.shan.hello.mappe r.DepartmentMapper.get"
column="dept_id"
/>
</resultMap>
(2)使用额外的 SQL 做映射配置会导致的问题:N+1问题
例如:每个员工的部门编号dept_id 是不同的,当查询所有员工的id、name、所属的部门名称的信息时就会发送额外N条SQL语句。
N:发送额外N条SQL语句去查询员工所属的部门名称: select name from department where id = dept_id;
1:查询所有员工的id、name、所属的部门的编号dept_id:select * from employee;
----解决:使用内联映射(多表查询),此时一条 SQL 语句搞定。
----处理多表查询的结果集的方法:内联映射。
(3)对象关联的查询:
方式一:额外的SQL
方式二:内联映射
(4)处理多表查询的结果集的方法【内联映射】:
方式一:属性名-列名 通过resultMap的
子元素result进行映射配置[内联映射-使用result]:

方式二:属性名-列名 通过resultMap的
子元素association进行映射配置[内联映射-使用association]

(5)多对一关系配置总结:
★使用association元素,配置单一对象属性。
- 方式一:额外的SQL[分步查询],一般需要进入另外一个页面展示更加详细的信息。
- 方式二:内联映射[多表查询],常用。需要在列表中显示关联对象的数据,使用内联映射,否则会出现N+1问题。
2、一对多关系配置:
---例子:一个部门有多个员工。
(1)一对多关系-额外的SQL:
<!-- 针对单一对象的属性,使用association元素 -->
<!-- 针对集合类型的属性,使用collection元素 -->
<!-- 额外的SQL配置方式
collection元素:配置集合类型元素的关联关系
property 属性:对象的属性
select 属性:发送额外的sql
column 属性: 将指定的列的值传递给额外sql
-->
<resultMap id="BaseResultMap" type="Department">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--<result column="" property="emps"/> -->
<collection property="emps"
select="com.shan.hello.mapper.EmployeeMapper.get"
column="id" >
</collection>
</resultMap>
<select id="get" resultMap="BaseResultMap">
select id, name from department where id = #{id}
</select>
(2)一对多关系-内联查询:
<!-- 针对单一对象的属性,使用association元素 -->
<!-- 针对集合类型的属性,使用collection元素 -->
<resultMap id="BaseResultMap" type="Department">
<id column="id" property="id"/>
<result column="name" property="name"/>
<!--<result column="" property="emps"/> -->
<!--
内联查询:ofType是集合中泛型的类型
-->
<collection property="emps" ofType="Employee">
<result column="e_id" property="id"/>
<result column="e_name" property="name"/>
<result column="e_dept_id" property="deptId"/>
</collection>
</resultMap>
<select id="get" resultMap="BaseResultMap">
<!-- select id, name from department where id = #{id} -->
select d.id, d.name, e.id e_id, e.name e_name, e.dept_id e_dept_id from department d
join employee2 e on d.id = e.dept_id where d.id = #{id}
</select>
二、设置延迟/懒加载
<!-- 全局配置文件 -->
<settings>
<!-- 懒加载/延迟加载,开启延迟加载功能 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 设置不要积极地去查询关联对象 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 延迟加载的触发方法 -->
<setting name="lazyLoadTriggerMethods" value="close"/>
</settings>
- 动态代理-增强功能--延迟加载
总结:多对一、一对多关系的单属性对象/集合属性对象,使用association或collection元素?使用额外SQL或内联查询?
针对【单属性对象】:使用
assoication元素,通常需要使用多表查询操作,即内联查询针对【集合属性对象】:使用
collection元素,通常还要使用延迟加载,即额外SQL处理
MyBatis加强(1)~myBatis对象关系映射(多对一关系、一对多关系)、延迟/懒加载的更多相关文章
- 019 关联映射文件中集合标签中的lazy(懒加载)属性
<set>.<list>集合上,可以取值:true/false/extra,(默认值为:true) 实例一:(集合上的lazy=true(默认))class默认lazy=tru ...
- 018 关联映射文件中<class>标签中的lazy(懒加载)属性
Lazy(懒加载): 只有在正真使用该对象时,才会创建这个对象 Hibernate中的lazy(懒加载): 只有我们在正真使用时,它才会发出SQL语句,给我们去查询,如果不使用对象则不会发SQL语句进 ...
- hibernate学习五(关系映射多对一与一对多)
一.多对一 多对一(或者一对多):在学生与老师的情况下,一个老师可以教多个学生,但一个学生只能被教一个老师教: 对于类:在多的那方拥有一的那方的一个实体 二.修改student.java和teache ...
- mybatis(三)懒加载
懒加载的好处: 所谓懒加载(lazy)就是延时加载,延迟加载.什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载.至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为 ...
- 关于 Mybatis 设置懒加载无效的问题
看了 mybatis 的教程,讲到关于mybatis 的懒加载的设置: 只需要在 mybatis 的配置文件中设置两个属性就可以了: <settings> <!-- 打开延迟加载的开 ...
- MyBatis --- 映射关系【一对一、一对多、多对多】,懒加载机制
映射(多.一)对一的关联关系 1)若只想得到关联对象的id属性,不用关联数据表 2)若希望得到关联对象的其他属性,要关联其数据表 举例: 员工与部门的映射关系为:多对一 1.创建表 员工表 确定其外键 ...
- Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射
一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...
- Spring Data JPA 关系映射(一对一,一对多,多对多 )
CascadeType.REMOVE 级联删除操作,删除当前实体时,与它有映射关系的实体也会跟着被删除.CascadeType.MERGE 级联更新(合并)操作,当Student中的数据改变,会相应地 ...
- mybatis 详解(八)------ 懒加载
本章我们讲如何通过懒加载来提高mybatis的查询效率. 本章所有代码:http://pan.baidu.com/s/1o8p2Drs 密码:trd6 1.需求:查询订单信息,有时候需要关联查出用户信 ...
随机推荐
- hdu-5568SUM (dp)
sequence2 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- 第四十九个知识点:描述在IPsec和TLS后的基本想法
第四十九个知识点:描述在IPsec和TLS后的基本想法 网络安全协议(Internet Protocol Security,IPsec)和安全传输层协议(Transport Layer Securit ...
- 基于 Electron 的 Rubick 2.4k star 啦,同步更新新功能!
为什么要做 Rubick 其实做 Rubick 1.x 的初衷就是解决自己的问题的:特别需要一款支持自定义插件的桌面端应用来简化使用者安装庞大桌面端应用的臃肿.而且涉及到数据安全的问题,插件只能在公司 ...
- Capstone CS5265替代龙迅LT8711|设计TYPEC转HDMI2.0投屏方案|替代龙迅LT8711方案
LT8711是一款高性能C型/DP1.2至HDMI2.0转换器,设计用于将USB typec或DP1.2源连接至HDMI2.0接收器.LT8711集成了兼容DP1.2的接收机和兼容HDMI2.0的发射 ...
- CentOS7.6下安装Redis5.0.7
此次安装是在CentOS7下安装Redis5.0.7 一.首先准备Redis安装包 这里下载的是 redis-5.0.7.tar.gz 安装包,并将其直接放在了 root ⽬录下 压缩包下载地址:ht ...
- Linux-saltstack-1 saltstack的安装与基本配置
@ 目录 一.环境介绍 二.安装saltstack 1.配置安装yum源 2.安装salt-master 3.安装slat-minion 三.配置salt-master 1.指定master的地址 2 ...
- Pytest_Hook函数pytest_addoption(parser):定义自己的命令行参数(14-1)
考虑场景: 我们的自动化用例需要支持在不同测试环境运行,有时候在dev环境运行,有时候在test环境运行: 有时候需要根据某个参数不同的参数值,执行不同的业务逻辑: 上面的场景我们都可以通过" ...
- Docker_容器(container)使用(4)
参数说明 -i: 交互式操作. -t: 终端. -d: 指定容器运行模式. --name:指定容器的NAMES字段名称,不指定则随机生成名称 --restart:容器启动策略.默认为no,常用为alw ...
- Python 安装第三方模块时 报Retrying(Retry(total=4, connect=None, read=None, redirect=None, status=None))...[WinError 10061]由于目标计算机积极拒绝,无法连接 错误
今日在安装ddt模块时(Windows系统),cmd报了一个以前从未见过的错误,如下图所示: 经百度,知是镜像源的问题,将安装命令改成如下命令: pip install ddt -i https:// ...
- VsCode安装与配置
一.安装 二.配置 开启emmet完整的语法 文件-首选项-设置:Emmet: Trigger Expansion On Tab 三.常用插件 必装: Chinese (Simplified) Lan ...