14.1     什么是延迟加载

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

  需求:

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

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

14.2     使用association实现延迟加载

14.2.1     需求

  查询订单并且关联查询用户信息

14.2.2      mapper.xml

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

  1、只查询订单信息

  SELECT * FROM orders

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

    <!-- 查询订单关联查询用户,用户信息需要延迟加载 -->

    <select id="findOrdersUserLazyLoading" resultMap="OrdersUserLazyLoadingResultMap">
SELECT * FROM orders
  </select>

  2、关联查询用户信息

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

  使用UserMapper.xml中的findUserById

   <select id="findUserById" parameterType="int" resultType=" User">
SELECT * FROM USER WHERE id=#{value}
</select>

  上边先去执行findOrdersUserLazyLoading,当需要去查询用户的时候再去执行findUserById,通过resultMap的定义将延迟加载执行配置起来。

14.2.3     延迟加载resultMap

 <!-- 延迟加载的resultMap -->
<resultMap type="Orders" id="OrdersUserLazyLoadingResultMap"> <!--对订单信息进行映射配置 -->
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/> <!-- 实现对用户信息进行延迟加载
select:指定延迟加载需要执行的statement的id(是根据user_id查询用户信息的statement)
要使用userMapper.xml中findUserById完成根据用户id(user_id)用户信息的查询,如果findUserById不在本mapper中需要前边加namespace
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="User"
select="findUserById" column="user_id">
<!-- 实现对用户信息进行延迟加载 -->
</association>
</resultMap>

14.2.4      mapper.java

 //查询订单关联查询用户,用户信息是延迟加载
public List<Orders> findOrdersUserLazyLoading();

14.2.5     测试

14.2.5.1              测试思路

  1、执行上边mapper方法(findOrdersUserLazyLoading),内部去调用com.styuan.practice.mybatis.query.dao.OrderMapper.findOrdersUserLazyLoading()

  中的findOrdersUserLazyLoading只查询orders信息(单表)。

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

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

14.2.5.2              延迟加载配置

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

  在mybatis核心配置文件中配置:

  lazyLoadingEnabled、aggressiveLazyLoading

设置项

描述

允许值

默认值

lazyLoadingEnabled

全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。

true | false

false

aggressiveLazyLoading

当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。

true | false

true

  在SqlMapConfig.xml中配置:

 <!-- 全局配置参数,需要时再设置 -->
<settings>
<!-- 打开延迟加载 的开关 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 将积极加载改为消极加载即按需要加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

14.2.5.3              测试代码

// 查询订单关联查询用户,用户信息使用延迟加载
@Test
public void testFindOrdersUserLazyLoading() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();// 创建代理对象
OrderMapper ordersMapperCustom = sqlSession.getMapper(OrderMapper.class); // 查询订单信息(单表)
List<Orders> list = ordersMapperCustom.findOrdersUserLazyLoading(); // 遍历上边的订单列表
for (Orders orders : list) { // 执行getUser()去查询用户信息,这里实现按需加载
User user = orders.getUser();
System.out.println(user);
}
}

14.2.5.4              延迟加载思考

  不使用mybatis提供的association及collection中的延迟加载功能,如何实现延迟加载??

  实现方法如下:

  定义两个mapper方法:

  1、查询订单列表

  2、根据用户id查询用户信息

  实现思路:

  先去查询第一个mapper方法,获取订单信息列表

  在程序中(service),按需去调用第二个mapper方法去查询用户信息。

  总之:

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

mybatis系列-14-延迟加载的更多相关文章

  1. 【mybatis深度历险系列】延迟加载

    在前面的博文中,小编主要简单的介绍了mybatis中的高级映射,小伙伴们可以把mybatis和hibernate的因素进行对比,更加有利于理解.今天这篇博文,小编主要来简单介绍一下mybatis中的延 ...

  2. MyBatis 系列五 之 延迟加载、一级缓存、二级缓存设置

    MyBatis的延迟加载.一级缓存.二级缓存设置 首先我们必须分清延迟加载的适用对象 延迟加载 MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟加载规则推迟对关联对象的se ...

  3. Mybatis 系列4

    上篇系列3中 介绍了properties与environments, 本篇继续讲剩下的配置节点之一:typeAliases. typeAliases节点主要用来设置别名,其实这是挺好用的一个功能, 通 ...

  4. Mybatis 系列3

    系列文章 2 中,我们通过对mybatis源码的简单分析,可看出,在mybatis配置文件中,在configuration根节点下面,可配置properties.typeAliases.plugins ...

  5. Mybatis 系列2

    上篇文章 写了一个Demo简单体现了一下Mybatis的流程.本次,将简单介绍一下Mybatis的配置文件: 上次例子中,我们以 SqlSessionFactoryBuilder 去创建 SqlSes ...

  6. Mybatis 系列1

    第一篇教程, 就先简单地写个demo, 一起来认识一下mybatis吧. 为了方便,我使用了maven, 至于maven怎么使用, 我就不做介绍了.没用过maven的, 也不影响阅读. 一.Mybat ...

  7. Mybatis 系列4-结合源码解析节点:typeAliases

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  8. Mybatis 系列3-结合源码解析properties节点和environments节点

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  9. Mybatis 系列2-配置文件

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  10. Mybatis 系列1-环境搭建

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

随机推荐

  1. javascript Klass 实现

    var Klass=function(Parent,props){ var Child,F,i; Child=function(){ if(Child.uber && Child.ub ...

  2. linux怎么运行.SH文件

    执行sh xx.sh命令就可以执行.sh文件了.如果直接执行xx.sh文件,就报权限错误 解决办法:执行chmod u+x xx.sh 来添加执行权限

  3. 360每日自动签到,领取积分 (java httpclient4.x)

    如何登陆360,并每日自动签到这次的难点主要集中在登陆这里了,开始抓包发现360登陆验证很麻烦,但是后来发现一个简单的方法.因为我安装了360安全卫士,发现点击那个金币的按钮能直接验证登陆,哈哈~所以 ...

  4. 浅谈学习C++时用到的【封装继承多态】三个概念

    封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...

  5. sysfs实例

    转自:http://blog.chinaunix.net/u1/51562/showart_1076295.html 一:前言 在设备模型中,sysfs文件系统用来表示设备的结构.将设备的层次结构形象 ...

  6. [HDOJ3466]Proud Merchants(贪心+01背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3466 n个商人,每个商人有一个物品,物品有价格p.价值v还有一个交易限制q.q的意义是假如你现在拥有的 ...

  7. UNIX / Linux: 2 Ways to Add Swap Space Using dd, mkswap and swapon

    UNIX / Linux: 2 Ways to Add Swap Space Using dd, mkswap and swapon by RAMESH NATARAJAN on AUGUST 18, ...

  8. 基于UltraVNC实现客户端远程控制

    前言 一般远程就直接用windows自带的,配置好动态IP花生壳,在任何地方都可以连回机子.最近项目里遇到这么个情况,需要快速接入远程控制功能,客户机的IP每次都会变,并且都是在外网,这样,就必须使用 ...

  9. 【英语】Bingo口语笔记(52) - sleep系列

  10. Activity传递对象的方法

    //Serializeable传递对象的方法 public void SerializeMethod(){ Person mPerson = new Person(); mPerson.setName ...