MyBatis分步查询的延迟加载
- 延迟加载的概念只存在于分步查询时;
- 延迟加载的本质是为第一步查询返回的Java Bean创建了一个代理对象;
- 延迟加载的全局设置有两个:
- lazyLoadingEnabled,作用为设置select语句的默认延迟加载是否开启;
aggressiveLazyLoading,对于开启了延迟加载的select作用如下:
- 值为true时,假设select返回的Java Bean为xxx,那么获取任何xxx属性的动作都会导致resultMap中定义的所有关联查询马上执行;
- 值为false时,假设yyy为xxx的一个属性,由关联查询获取,那么只有在yyy的某一属性被使用时,获取yyy的关联查询才会执行
- 延迟加载针对单个查询的具体设置为resultMap的 fetchType属性;
- 全局设置lazyLoadingEnabled和具体设置fetchType的关系如下:
- 如果设置了resultMap的 fetchType属性,那么全局设置lazyLoadingEnabled便不再对该select生效,是否延迟加载要以fetchType属性为准;
- 如果select的resultMap没有设置 fetchType属性,那么该select会采用lazyLoadingEnabled的设置;
- aggressiveLazyLoading只对延迟加载的select生效
演示如下
需要注意的是,一下演示在DEBUG模式下不成立,均为RUN模式;DEBUG模式下(IDEA环境)MyBatis不会延迟加载
E-R图:一个City隶属于一个Country,同时一个City包含多个Address
实体类:CityPlusPlus中包含一个Country和多个Address
CityPlusPlus
public class CityPlusPlus {
private Long id;
private String name;
private Long countryId;
private Date lastUpdate;
private Country country;
private List<Address> addressList;
}
Country
public class Country {
Long id;
String name;
Date lastUpdate;
}
Address
public class Address {
Long addressId;
String address;
String address2;
String district;
String postalCode;
String phone;
Long cityId;
Location location;
Date lastUpdate;
}
lazyLoadingEnabled和aggressiveLazyLoading均为true,fetchType不设置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="canger.study.chapter04.mapper.CityPlusPlusMapper"> <resultMap id="cityPlusPlusResultMap" type="canger.study.chapter04.bean.CityPlusPlus">
<id column="city_id" property="id"/>
<result column="city" property="name"/>
<result column="country_id" property="countryId"/>
<result column="last_update" property="lastUpdate"/>
<association property="country"
select="canger.study.chapter04.mapper.CountryMapper.selectCountryById"
column="country_id"/>
<association property="addressList"
select="canger.study.chapter04.mapper.AddressMapper.selectAddressesByCityId"
column="city_id"/>
</resultMap> <select id="selectCityPlusPlusById" resultMap="cityPlusPlusResultMap">
select *
from city
where city_id=#{id}
</select>
</mapper>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
测试代码如下:
@Test
public void testCityPlusPlusMapper(){
SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.initSqlSessionFactory();
SqlSession sqlSession = null; try {
sqlSession = sqlSessionFactory.openSession();
CityPlusPlusMapper mapper = sqlSession.getMapper(CityPlusPlusMapper.class);
System.out.println("************开始主动查询**************");
CityPlusPlus cityPlusPlus = mapper.selectCityPlusPlusById(42L);
System.out.println("*************主动查询结束*************");
System.out.println(cityPlusPlus.getName());
System.out.println("*************Step2*************");
System.out.println(cityPlusPlus.getCountry());
System.out.println("**************Step3************");
System.out.println(cityPlusPlus.getAddressList());
System.out.println();
System.out.println();
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
sqlSession.rollback();
} finally {
sqlSession.close();
}
}
日志输出如下,可以看到,当调用 cityPlusPlus.getName() 时,两个关联查询均马上执行
************开始主动查询**************
[DEBUG] 2018-11-21 23:37:12,307(300) --> [main] org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:137): Opening JDBC Connection
[DEBUG] 2018-11-21 23:37:12,552(545) --> [main] org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:406): Created connection 1514160588.
[DEBUG] 2018-11-21 23:37:12,553(546) --> [main] org.apache.ibatis.transaction.jdbc.JdbcTransaction.setDesiredAutoCommit(JdbcTransaction.java:101): Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5a4041cc]
[DEBUG] 2018-11-21 23:37:12,555(548) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Preparing: select * from city where city_id=?
[DEBUG] 2018-11-21 23:37:12,575(568) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Parameters: 42(Long)
[DEBUG] 2018-11-21 23:37:12,631(624) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): <== Total: 1
*************主动查询结束*************
[DEBUG] 2018-11-21 23:37:12,632(625) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Preparing: select * from country where country_id=?
[DEBUG] 2018-11-21 23:37:12,637(630) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Parameters: 103(Integer)
[DEBUG] 2018-11-21 23:37:12,640(633) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): <== Total: 1
[DEBUG] 2018-11-21 23:37:12,641(634) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Preparing: select address_id,address,address2,district,city_id,postal_code,phone,astext(location) as location,last_update from address where city_id=?
[DEBUG] 2018-11-21 23:37:12,641(634) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Parameters: 42(Integer)
[DEBUG] 2018-11-21 23:37:12,651(644) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): <== Total: 2
Aurora
*************Step2*************
Country{id=103, name='United States', lastUpdate=Wed Feb 15 04:44:00 CST 2006}
**************Step3************
[Address{addressId=335, address='587 Benguela Manor', address2='', district='Illinois', postalCode='91590', phone='165450987037', cityId=42, location=POINT(-88.3200762 41.760583), lastUpdate=Thu Sep 25 22:33:44 CST 2014}, Address{addressId=543, address='43 Vilnius Manor', address2='', district='Colorado', postalCode='79814', phone='484500282381', cityId=42, location=POINT(-104.8319273 39.729439), lastUpdate=Thu Sep 25 22:33:44 CST 2014}]
lazyLoadingEnabled为true和aggressiveLazyLoading为false,fetchType不设置
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
输出日志,可以看到:
- 当调用cityPlusPlus.getCountry() 时,第一个关联查询执行
- 当调用cityPlusPlus.getAddressList()时,第二个关联查询执行
************开始主动查询**************
[DEBUG] 2018-11-21 23:56:04,599(286) --> [main] org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:137): Opening JDBC Connection
[DEBUG] 2018-11-21 23:56:04,829(516) --> [main] org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:406): Created connection 1514160588.
[DEBUG] 2018-11-21 23:56:04,830(517) --> [main] org.apache.ibatis.transaction.jdbc.JdbcTransaction.setDesiredAutoCommit(JdbcTransaction.java:101): Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@5a4041cc]
[DEBUG] 2018-11-21 23:56:04,844(531) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Preparing: select * from city where city_id=?
[DEBUG] 2018-11-21 23:56:04,865(552) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Parameters: 42(Long)
[DEBUG] 2018-11-21 23:56:04,941(628) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): <== Total: 1
*************主动查询结束*************
Aurora
*************Step2*************
[DEBUG] 2018-11-21 23:56:04,942(629) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Preparing: select * from country where country_id=?
[DEBUG] 2018-11-21 23:56:04,943(630) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Parameters: 103(Integer)
[DEBUG] 2018-11-21 23:56:04,956(643) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): <== Total: 1
Country{id=103, name='United States', lastUpdate=Wed Feb 15 04:44:00 CST 2006}
**************Step3************
[DEBUG] 2018-11-21 23:56:04,961(648) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Preparing: select address_id,address,address2,district,city_id,postal_code,phone,astext(location) as location,last_update from address where city_id=?
[DEBUG] 2018-11-21 23:56:04,961(648) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): ==> Parameters: 42(Integer)
[DEBUG] 2018-11-21 23:56:04,971(658) --> [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159): <== Total: 2
[Address{addressId=335, address='587 Benguela Manor', address2='', district='Illinois', postalCode='91590', phone='165450987037', cityId=42, location=POINT(-88.3200762 41.760583), lastUpdate=Thu Sep 25 22:33:44 CST 2014}, Address{addressId=543, address='43 Vilnius Manor', address2='', district='Colorado', postalCode='79814', phone='484500282381', cityId=42, location=POINT(-104.8319273 39.729439), lastUpdate=Thu Sep 25 22:33:44 CST 2014}]
MyBatis分步查询的延迟加载的更多相关文章
- mybatis分步查询与延迟加载
1.分步查询 先查询用户的部门 部门Mapper.xml <resultMap id="rMap" type="com.yunqing.mybatis.bean.D ...
- MyBatis学习——分步查询与延迟加载
声明:面试是遇到延迟加载问题,在网页搜索到此篇文章,感觉很有帮助,留此学习之用! 一.分步查询 分步查询通常应用于关联表查询,如:电商平台,查询订单信息时需要查询部分的用户信息:OA系统查询个人信息时 ...
- Mybatis3.1-[tp_34-35]-_映射文件_select_resultMap关联查询_collection定义关联集合封装规则_collection分步查询_延迟加载
笔记要点出错分析与总结工程组织 1.定义接口 interface DepartmentMapper package com.dao; import com.bean.Department; publi ...
- Mybatis3.1-[tp_32-33]-_映射文件_select_resultMap关联查询_association分步查询_延迟加载
笔记要点出错分析与总结 工程组织 1.定义接口 DepartmentMapper package com.dao; import com.bean.Department; public interfa ...
- MyBatis联合查询和使用association 进行分步式查询
查询Emp的同时,查出emp对应的部门Department 方法1:联合查询,使用级联属性封装结果集 <!-- 联合查询,使用级联属性封装结果集 type:要自定义规则的javaBean类型 i ...
- mybatis使用associaton进行分步查询
Employee类 public class Employee { private Integer id; private String lastName; private String email; ...
- Java框架之MyBatis 06-全局配置-mapper映射-分步查询
MyBatis MyBatis是Apache的一个开源项目iBatis, iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架. iBatis 提供的持 ...
- Mybatis源码分析--关联表查询及延迟加载原理(二)
在上一篇博客Mybatis源码分析--关联表查询及延迟加载(一)中我们简单介绍了Mybatis的延迟加载的编程,接下来我们通过分析源码来分析一下Mybatis延迟加载的实现原理. 其实简单来说Myba ...
- mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存
关本文是Mybatis基础系列的第四篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(三)——动态sql mybatis基础系列(二)——基础语法.别名.输入映射.输出映射 mybat ...
随机推荐
- $\rm{NOIp}$板子整理
怎么说呢,整理这个的目的就是为了有个简约的\(list\),方便以后查阅,复习起来不至于太吃力. 并且--好像重温一遍所有,会更有一些新的认识.这也算是对我所学的一点整理了吧. 一.并查集的两种方式 ...
- php操作文件类的函数
<?php /** // 一行一行读取一个文件 (文件内容很大的时候,适用.file_get_contents此场景就不太好) $re = fopen("index.php" ...
- 20155234 《网络对抗》Exp 8 Web基础
基础问答 什么是表单 可以收集用户的信息和反馈意见,是网站管理者与浏览者之间沟通的桥梁. 表单包括两个部分:一部分是HTML源代码用于描述表单(例如,域,标签和用户在页面上看见的按钮),另一部分是脚本 ...
- 20155308《网络攻防》 Exp1 PC平台逆向破解(5)M
20155308<网络攻防> Exp1 PC平台逆向破解(5)M 逆向及Bof基础实践说明 1.1 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是 ...
- WPF编程,通过KeyFrame 类型制作控件线性动画的一种方法。
原文:WPF编程,通过KeyFrame 类型制作控件线性动画的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/articl ...
- JS计算混合字符串长度
用的是正则表达式 var str = ”坦克是tank的音译”; var len = str.match(/[^ -~]/g) == null ? str.length : str.length + ...
- 使用不同的方法计算TF-IDF值
摘要 这篇文章主要介绍了计算TF-IDF的不同方法实现,主要有三种方法: 用gensim库来计算tfidf值 用sklearn库来计算tfidf值 用python手动实现tfidf的计算 总结 之所以 ...
- 基于.NET的3D开发框架/工具比较
好久木有写博客了,这么日子以来忙忙碌碌的,也没大有时间潜心学习和梳理.最近刚好接手一个3D显示的活,虽然还没怎么弄明白,但是也看过一些方案,走了一些弯路,经过一些浅显的了解(3D Display这里面 ...
- SpringBoot日记——MQ消息队列整合(一)
除了之前讲到的缓存,我们还会用到消息队列来存储一些消息,为了提升系统的异步性能等等: 消息服务有两个概念需要知道:消息代理-message broker,目的地-destination.消息发送由代理 ...
- OPENSTACK重装系统失败导致虚拟机状态为error
重装系统失败导致虚拟机状态为error DASHBOARD查看虚拟机状态: 查看日志: 磁盘不足导致下载新镜像失败. Virsh list -all 无法发现虚拟机,底层盘消失(因为重装系统时nova ...