一、什么是延迟加载

resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。

需求:如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。

延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。

 二、使用association实现延迟加载

需要定义两个mapper的方法对应的statement。

1、只查询订单信息

  SELECT * FROM orders

在查询订单的statement中使用association去延迟加载(执行)下边的satatement(关联查询用户信息)

2、关联查询用户信息

  通过上边查询到的订单信息中user_id去关联查询用户信息

OrdersCustomMapper.xml的延迟加载的核心代码:

  使用association中的select指定延迟加载去执行的statement的id。

<!-- 查询订单关联查询用户,用户信息按需延迟加载 的 resultMap定义 -->
<resultMap type="com.mybatis.entity.Orders" id="ordersUserLazyLoading">
<!--对订单信息进行映射配置 -->
<id column="id" property="id"/>
<result column="number" property="number"/>
<result column="createtime" property="createTime"/>
<result column="note" property="note"/>
<!-- 实现对用户信息进行延迟加载
select:指定延迟加载需要执行的statement的id(是根据user_id查询用户信息的statement)
column:订单信息中关联用户信息查询的列,是user_id
关联查询的sql理解为:
SELECT orders.*,
(SELECT username FROM USER WHERE orders.user_id = user.id)username,
(SELECT sex FROM USER WHERE orders.user_id = user.id)sex
FROM orders
-->
<association property="user" javaType="com.mybatis.entity.User" select="findUserById" column="user_id"/>
</resultMap> <!-- 根据Id查询用户,用于测试延迟加载 -->
<select id="findUserById" parameterType="int" resultType="com.mybatis.entity.User" >
select * from t_user where id=#{id}
</select> <!-- 查询订单关联用户,用户信息延迟加载 -->
<select id="findOrdersUserLazyLoading" resultMap="ordersUserLazyLoading">
select * from orders
</select>

OrdersCustomMapper.java的代码:

/**查询订单,关联查询用户,用户按需延迟加载*/
public List<Orders>findOrdersUserLazyLoading(); /**根据Id查询用户(这个方法本应该放在UserMapper类的,测试方便先放在这)*/
public User findUserById(int id);

测试思路及代码:

1、执行上边mapper方法(findOrdersUserLazyLoading),内部去调用OrdersMapperCustom中的findOrdersUserLazyLoading只查询orders信息(单表)。

2、在程序中去遍历上一步骤查询出的List<Orders>,当我们调用Orders中的getUser方法时,开始进行延迟加载。

3、延迟加载,去调用findUserbyId这个方法获取用户信息。

// 查询用户关联查询用户,用户信息延迟加载
@Test
public void TestFindOrdersUserLazyLoading() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersCustomMapper oc = sqlSession.getMapper(OrdersCustomMapper.class);
// 调用mapper的方法
List<Orders> list = oc.findOrdersUserLazyLoading();
for(Orders order: list){
//执行getUser()去查询用户信息,这里实现延迟加载
User user = order.getUser();
System.out.println(user);
}
sqlSession.close();
}

注:项目中要引入cglib.jar和asm.jar。

三、延迟加载在mybatis核心配置文件sqlMapConfig.xml中的配置

mybatis默认没有开启延迟加载,需要在SqlMapConfig.xml中setting配置。

在mybatis核心配置文件中配置:lazyLoadingEnabled、aggressiveLazyLoading

设置项 描述 允许值 默认值
lazyLoadingEnabled 全局性设置懒加载。如果设为'false',则所有相关联的都会被初始化加载。 true | false false
aggressiveLazyLoading 当设置为'true'的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。 true | false true
<!-- 全局参数的配置 -->
<settings>
<!--打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!--将积极加载改为消极加载及按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

四、延迟加载的原理

它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。

小结:使用延迟加载方法,先去查询简单的sql(最好单表,也可以关联查询),再去按需要加载关联查询的其它信息。

Mybatis学习总结(八)——延迟加载的更多相关文章

  1. MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合(转载)

      孤傲苍狼 只为成功找方法,不为失败找借口! MyBatis学习总结(八)--Mybatis3.x与Spring4.x整合 一.搭建开发环境 1.1.使用Maven创建Web项目 执行如下命令: m ...

  2. mybatis学习记录七——延迟加载

    14       延迟加载 14.1     什么是延迟加载 resultMap可以实现高级映射(使用association.collection实现一对一及一对多映射),association.co ...

  3. MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合

    一.搭建开发环境 1.1.使用Maven创建Web项目 执行如下命令: mvn archetype:create -DgroupId=me.gacl -DartifactId=spring4-myba ...

  4. MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合

    一.搭建开发环境 1.1.使用Maven创建Web项目 执行如下命令: mvn archetype:create -DgroupId=me.gacl -DartifactId=spring4-myba ...

  5. MyBatis学习笔记(八)——Mybatis3.x与Spring4.x整合

    转自孤傲苍狼的博客:http://www.cnblogs.com/xdp-gacl/p/4271627.html 一.搭建开发环境 1.1.使用Maven创建Web项目 执行如下命令: mvn arc ...

  6. Mybatis学习笔记(八) —— Mybatis整合spring

    一.整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mapper代 ...

  7. mybatis学习(八)——resultMap之association&&collection解析

    一.resultMap的使用 resultMap 也是定义返回值类型,返回值为用户自定义的类型,可用于解决JavaBean中的属性名和数据库中的列名不一致的情况 之前对于JavaBean中属性名和数据 ...

  8. 转载-MyBatis学习总结

    MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合 孤傲苍狼 2015-02-07 00:09 阅读:89825 评论:54     MyBatis学习总结(七)——Myba ...

  9. 转:MyBatis学习总结(Mybatis总结精华文章)

    http://www.cnblogs.com/xdp-gacl/tag/MyBatis%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93/ 当前标签: MyBatis学习总结   ...

随机推荐

  1. Linux内核线程的思考与总结

    1.内核线程,只是一个称呼,实际上就是一个进程,有自己独立的TCB,参与内核调度,也参与内核抢占. 这个进程的特别之处有两点,第一.该进程没有前台.第二.永远在内核态中运行. 2.创建内核线程有两种方 ...

  2. 通俗的理解java设计模式的准则

    本文部分内容摘抄自https://www.cnblogs.com/dolphin0520/p/3919839.html,加入了自己的理解: 一.单一职责原则 原文链接:http://blog.csdn ...

  3. Native SBS for Android

    Native SBS for Android是一款非常棒的软件,支持安卓在2D界面下左右分屏显示,并可以设置缩放比例及左右间距,横屏自动切换为左右分屏显示模式,竖屏则为正常显示.启动左右分屏模式后,将 ...

  4. session,cookie,sessionStorage,localStorage的区别

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...

  5. Python笔记(十六):迭代器

    (一)iterable对象和Iterator对象的区别 iterable对象(可迭代的对象):可以使用for循环,例如:字符串.列表 .字典 .集合等 Iterator对象(迭代器):除了可以用for ...

  6. Python HTML解析模块HTMLParser(爬虫工具)

    简介 先简略介绍一下.实际上,HTMLParser是python用来解析HTML的内置模块.它可以分析出HTML里面的标签.数据等等,是一种处理HTML的简便途径.HTMLParser采用的是一种事件 ...

  7. python ddt

    #!/usr/bin/env/python # -*- coding: utf-8 -*- # @Time : 2018/12/15 15:27 # @Author : ChenAdong # @Em ...

  8. 腾讯云Centos安装gitlab

    参考了网上很多人写的安装教程,结果并不好,最后阅读了官方的英文api,才安装成功,这里记录下来,方便以后使用.我的安装环境为腾讯云主机Centos7.3 64bit gitlab官方api地址点我试试 ...

  9. MySQL 查看用户授予的权限

      在MySQL中,如何查看一个用户被授予了那些权限呢? 授予用户的权限可能分全局层级权限.数据库层级权限.表层级别权限.列层级别权限.子程序层级权限.具体分类如下: 全局层级 全局权限适用于一个给定 ...

  10. SQL语句计算距离今天生日还差几天

    转载于:http://www.w3dev.cn/article/20110125/sql-compute-birthdate-now-days.aspx SQL语句计算距离生日还差几天原理很简单,将要 ...