MyBatis Lazy Loading
MyBatis的Lazy Loading可以实现延迟查询Bean里的嵌套成员类,控制lazy loading的<settings>属性有
lazyLoadingEnabled: lazy loading开关,默认为true
aggressiveLazyLoading: 侵略性 lazy loading 开关, 默认为true, 这个属性比较搞笑,如果为true则当你访问任何一个属性都会加载所有的其他lazy load属性,即使你根本没有调用哪个lazy load属性,说白了就是aggressiveLazyLoading=true,则lazy load等于没用,所以要使用lazy load还是将其设为false
一个使用lazyload的例子
ResultMap
<!-- 使用子查询的方式查询成员变量 -->
<resultMap id="articleResultMap2" type="Article">
<id property="id" column="article_id" />
<result property="title" column="article_title" />
<result property="content" column="article_content" />
<association property="user" column="user_id" select="dao.userdao.selectUserByID"/>
</resultMap>
查询Mapper
<!-- 测试lazy load user -->
<select id="selectArticleById2" parameterType="int" resultMap="dao.base.articleResultMap2">
SELECT * FROM article WHERE id = #{id}
</select> <select id="selectUserByID" parameterType="int" resultType="User"
flushCache="false" useCache="true" timeout="10000" statementType="PREPARED">
SELECT
*
FROM user
WHERE id = #{id}
</select>
测试代码
public String getArticle2(Model model) {
Article article = articleDao.selectArticleById2(1);
// 如果你在这里打一个断点,你会发现还没有执行到getUser()这一句article.user已经被查询加载
// 而如果你将 getUser() 那行注释,则article.user在执行到这里也不会被加载
// 我的理解是java是编译型语言,mybatis可以根据编译好的中间码查看哪些属性被调用
// 然后在第一次执行sql的时候把后面将会调用到的延迟加载属性都提前加载了
// 另外,MyBatis有个更搞笑和骗人的地方是,如果你不在这里打断点,它lazy load的子查询就一定会出现在getUser()之后
// 而如果这里打了断点,则lazy load的子查询语句会在selectArticleById2()这个方法就出现了
System.out.println();
// 如果aggressiveLazyLoading为true,则getContent()的时候就会执行查询user的sql
// 即使你根本没有调用getUser(),也会将user属性查询出来,例如将getUser()那行注释了
System.out.println(article.getContent());
System.out.println("Lazy loading ......");
System.out.println(article.getUser());
return "index";
}
输出
DEBUG - ooo Using Connection [jdbc:mysql://127.0.0.1:3306/mybatistest?characterEncoding=utf8, UserName=root@localhost, MySQL-AB JDBC Driver]
DEBUG - ==> Preparing: SELECT * FROM article WHERE id = ?
DEBUG - ==> Parameters: 1(Integer)
DEBUG - Cache Hit Ratio [dao.userdao]: 0.0
DEBUG - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6bbe7]
DEBUG - Returning JDBC Connection to DataSourcetest_content
Lazy loading ......
DEBUG - Fetching JDBC Connection from DataSource
DEBUG - JDBC Connection [jdbc:mysql://127.0.0.1:3306/mybatistest?characterEncoding=utf8, UserName=root@localhost, MySQL-AB JDBC Driver] will not be managed by Spring
DEBUG - ooo Using Connection [jdbc:mysql://127.0.0.1:3306/mybatistest?characterEncoding=utf8, UserName=root@localhost, MySQL-AB JDBC Driver]
DEBUG - ==> Preparing: SELECT * FROM user WHERE id = ?
DEBUG - ==> Parameters: 1(Integer)
DEBUG - Returning JDBC Connection to DataSource
1|test1|19|beijing
抛开上面注释中MyBatis各种奇怪的表现不说,MyBatis的Lazy Loading是基于子查询select的,也是这段
<association property="user" column="user_id" select="dao.userdao.selectUserByID"/>
这个方式最大的问题是会产生N+1问题,假设article里的user是一个List<User>:
1. 使用一条SQL语句查询Article类(the 1)
2. 使用N条SQL查询Article里的List<User>
如果我们在查询Article以后需要遍历Article的List<User>,则会触发所有user的Lazy Loading
也就是说我们也无法使用JOIN去使用Lazy Loading,从而避免n+1的问题
MyBatis Lazy Loading的更多相关文章
- Angular2+typescript+webpack2(支持aot, tree shaking, lazy loading)
概述 Angular2官方推荐的应该是使用systemjs加载, 但是当我使用到它的tree shaking的时候,发现如果使用systemjs+rollup,只能打包成一个文件,然后lazy loa ...
- Lazyr.js – 延迟加载图片(Lazy Loading)
Lazyr.js 是一个小的.快速的.现代的.相互间无依赖的图片延迟加载库.通过延迟加载图片,让图片出现在(或接近))视窗才加载来提高页面打开速度.这个库通过保持最少选项并最大化速度. 在线演示 ...
- Can you explain Lazy Loading?
Introduction Lazy loading is a concept where we delay the loading of the object until the point wher ...
- [AngularJS] Lazy Loading modules with ui-router and ocLazyLoad
We've looked at lazy loading with ocLazyLoad previously, but what if we are using ui-router and want ...
- [AngularJS] Lazy loading Angular modules with ocLazyLoad
With the ocLazyLoad you can load AngularJS modules on demand. This is very handy for runtime loading ...
- iOS swift lazy loading
Why bother lazy loading and purging pages, you ask? Well, in this example, it won't matter too much ...
- Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading
Entity Framework提供了三种加载相关实体的方法:Lazy Loading,Eager Loading和Explicit Loading.首先我们先来看一下MSDN对三种加载实体方法的定义 ...
- Lazy Loading | Explicit Loading | Eager Loading in EntityFramework and EntityFramework.Core
EntityFramework Eagerly Loading Eager loading is the process whereby a query for one type of entity ...
- EFCore Lazy Loading + Inheritance = 干净的数据表 (二) 【献给处女座的DB First程序猿】
前言 本篇是上一篇EFCore Lazy Loading + Inheritance = 干净的数据表 (一) [献给处女座的DB First程序猿] 前菜 的续篇.这一篇才是真的为处女座的DB Fi ...
随机推荐
- LoadRunner 自带订票系统flights 功能空白、1080端口被占用的解决办法
LoadRunner 自带订票系统flights 功能空白.1080端口被占用的解决办法 安装LoadRunner8.1后运行Mercury Web Tours Application,点击fligh ...
- HTML5 Canvas游戏开发(四)lufylegend开源库件(下)
一.文本 LTextField对象是lufylegend库件中专门用于显示文本信息的一个对象. 1.文本属性 创建的文本框对象不会自动加入可视化对象列表中.只有手动调用addChild()方法才能使它 ...
- html+css制作五环(代码极简)
五环 把五环做成一个浮动,总是位于屏幕中央的效果. 难点 定位的练习 position :fixed 位于body中间的时候 left:50%:top:50%; css内部样式表的使用 style=& ...
- count 【mysql】
如果你的需要是统计总行数时,为什么要使用count(*),而避免使用指定具体的列名? count()函数里面的参数是列名的的时候,那么会计算这个字段有值项的次数.也就是,该字段没有值的项并不会进入计算 ...
- SERVLET API中forward()与redirect()的区别?
前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址:后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接.这样,从浏览器的地址栏中可以看到跳转后的链接地址.所以,前者 ...
- iOS 11开发教程(四)iOS11模拟器介绍一
iOS11模拟器介绍 在图1.6或者1.7中所看到的类似于手机的模型就是iOS模拟器.iOS模拟器是在没有iPhone或iPad设备时,对程序进行检测的设备.iOS模拟器可以模仿真实的iPhone或i ...
- Linux怎么开启ssh
一.查看ssh开启状态 service ssh status 这是已经开启了的状态 二.如果没有开启 键入以下命令开启 service ssh start 三.开启后如果不能利用xshell远程访问 ...
- 20162327WJH实验五——数据结构综合应用
20162327WJH实验五--数据结构综合应用 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验密级: 非密 ...
- [CC-MCHEF]MasterChef
[CC-MCHEF]MasterChef 题目大意: \(n(n\le10^5)\)片花,第\(i\)片花的美观度为\(b_i(|b_i|\le10^9)\).总体美观度为各片花的美观度之和. 由于有 ...
- 模仿JQuery 的添加多个事件的原理
var jquery=function(dom){ var obj={ ready:function(fn){ if(typeof dom.onload=="function"){ ...