一、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对象关系映射(多对一关系、一对多关系)、延迟/懒加载的更多相关文章

  1. 019 关联映射文件中集合标签中的lazy(懒加载)属性

    <set>.<list>集合上,可以取值:true/false/extra,(默认值为:true) 实例一:(集合上的lazy=true(默认))class默认lazy=tru ...

  2. 018 关联映射文件中<class>标签中的lazy(懒加载)属性

    Lazy(懒加载): 只有在正真使用该对象时,才会创建这个对象 Hibernate中的lazy(懒加载): 只有我们在正真使用时,它才会发出SQL语句,给我们去查询,如果不使用对象则不会发SQL语句进 ...

  3. hibernate学习五(关系映射多对一与一对多)

    一.多对一 多对一(或者一对多):在学生与老师的情况下,一个老师可以教多个学生,但一个学生只能被教一个老师教: 对于类:在多的那方拥有一的那方的一个实体 二.修改student.java和teache ...

  4. mybatis(三)懒加载

    懒加载的好处: 所谓懒加载(lazy)就是延时加载,延迟加载.什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载.至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为 ...

  5. 关于 Mybatis 设置懒加载无效的问题

    看了 mybatis 的教程,讲到关于mybatis 的懒加载的设置: 只需要在 mybatis 的配置文件中设置两个属性就可以了: <settings> <!-- 打开延迟加载的开 ...

  6. MyBatis --- 映射关系【一对一、一对多、多对多】,懒加载机制

    映射(多.一)对一的关联关系 1)若只想得到关联对象的id属性,不用关联数据表 2)若希望得到关联对象的其他属性,要关联其数据表 举例: 员工与部门的映射关系为:多对一 1.创建表 员工表 确定其外键 ...

  7. Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射

    一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...

  8. Spring Data JPA 关系映射(一对一,一对多,多对多 )

    CascadeType.REMOVE 级联删除操作,删除当前实体时,与它有映射关系的实体也会跟着被删除.CascadeType.MERGE 级联更新(合并)操作,当Student中的数据改变,会相应地 ...

  9. mybatis 详解(八)------ 懒加载

    本章我们讲如何通过懒加载来提高mybatis的查询效率. 本章所有代码:http://pan.baidu.com/s/1o8p2Drs 密码:trd6 1.需求:查询订单信息,有时候需要关联查出用户信 ...

随机推荐

  1. Matrix(poj2155)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 25139   Accepted: 9314 Descripti ...

  2. 晴天小猪历险记之Hill(Dijkstra优先队列优化)

    描述 这一天,他来到了一座深山的山脚下,因为只有这座深山中的一位隐者才知道这种药草的所在.但是上山的路错综复杂,由于小小猪的病情,晴天小猪想找一条需时最少的路到达山顶,但现在它一头雾水,所以向你求助. ...

  3. IntelliJ IDEA打war包

    1.按ctrl+alt+shift+s键打开Project Structure,点击+号图标,选择"Artifacts->Web Application Archive" 2 ...

  4. 【嵌入式】arduino IDE串口监视器可以正常使用但其他软件发送串口指令没有反应的问题

    解决办法: 1.检查 波特率baudrate 是否一致 2.检查 数据位长度databits 是否一致 3.检查 停止位长度stopbits 是否一致 4.检查 奇偶校验位 是否一致 5.(特殊)是否 ...

  5. Order Statistic

    目录 The Order Statistic 引理1 的一些基本性质 顺序统计量的分布 顺序统计量的条件分布 特殊分布的特殊性质 Order Statistic The Order Statistic ...

  6. CONTRASTIVE REPRESENTATION DISTILLATION

    目录 概 主要内容 超参数的选择 代码 Tian Y., Krishnan D., Isola P. CONTRASTIVE REPRESENTATION DISTILLATION. arXiv pr ...

  7. uniCloud爬虫获取网页数据

    'use strict'; let request = require('request') let cheerio = require('cheerio'); //爬虫 let iconv = re ...

  8. CS229 机器学习课程复习材料-线性代数

    本文是斯坦福大学CS 229机器学习课程的基础材料,原始文件下载 原文作者:Zico Kolter,修改:Chuong Do, Tengyu Ma 翻译:黄海广 备注:请关注github的更新,线性代 ...

  9. 【优雅代码】01-lombok精选注解及原理

    [优雅代码]01-lombok精选注解及原理 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺手点 ...

  10. Java初学者作业——编写程序计算实发工资(实践1)

    返回本章节 返回作业目录 需求说明: 腾讯为Java工程师提供了基本工资(8000元).物价津贴及房租津贴.其中物价津贴为基本工资的40%,房屋津贴为基本工资的25%.要求编写程序计算实发工资. 实现 ...