MyBatis:lazy loading
懒加载的原理
mybatis 会循环处理结果集中返回的每行数据的,在处理之前首先会通过反射调用构造方法来创建 result 对象,结果集中的一行数据最终会映射为一个 result 对象(严格的来说是不对的,结果集中的一行数据在多表连接的情况下可能会映射为多个 result 对象,结果集中的一行数据在多表连接一对多的情况下结果集中的多行数据可能映射一个 result 对象,简单的单表查询结果集中的一行数据映射为一个 result 对象)。
其实在调用构造方法创建 result 对象的时候,构造方法还可能会有参数,需要先把结果集中的参数都提取出来,传给相应的构造方法通过反射创建对象。
mybatis 其实第一步是解析配置文件,把配置文件映射为 mybatis 的 Configuration 类,把配置文件的 xml 属性都映射为 Java 对象中的属性值。xml mapper 文件的处理比较复杂,< resultMap/> 标签映射为 ResultMap 对象, 标签中的< id/> 、< result/>、< association/> 等映射为 ResultMapping 对象。
其实要讲 mybatis 的实现过程,涉及到的点太多了,没法在一篇博客中讲。在这里,我只简单的讲一下原理。
接着再讲创建好 result 对象之后,mybatis 会循环 resultMappings(标签中的每个子标签都映射为一个 resultMapping,这些 resultMapping 组成了一个集合就是 resultMappings)集合,看有没有需要懒加载的属性,如果有的话,则会为这个 result 对象创建一个代理对象。
什么情况下才会出现需要懒加载的属性呢?只有 < association property=”author” column=”author_id” select=”selectAuthor” fetchType=”lazy”/>
和 < collection property=”xxx” column=”xxx” select=”xxxx” fetchType=”lazy”/> 作为一个子标签出现在 < resultMap/> 标签(也不一定只是 < resultMap/> 标签,< collection/> 等标签事实上也算是一个 < resultMap/> 标签)之内才会出现需要懒加载的属性。select 属性和 fetchType=”lazy” 必须同时出现在 < collection/> 或 < association/> 属性中才需要懒加载,select 表示的是嵌套查询语句的 id ,fetchType=”lazy” 表示的是懒加载。
再接着讲 result 对象的代理对象,代理类是由 javassist 框架在运行时创建和加载的,这个代理类继承自 result 对象所属的类,以上面的例子为例,这个代理类继承自 Blog 类。
对于这个代理类的详细讲解在我的博客深入理解 Java 动态代理中有很详细的介绍,在这里我再简单的介绍下。
这个代理类继承了 result 对象所属的类(被代理类)并重写了被代理类的所有的方法,所以在代理对象上调用懒加载属性的 get 方法(getAuthor())时会触发懒加载动作,mybatis 这时就能发现需要去懒加载一个属性,然后去加载这个属性。
其实,有几个方法都可以触发懒加载的操作,比如调用懒加载的 get/set 方法(确实调用 set 方法时也会触发懒加载操作)还有调用 clone()、equals()、hashCode()、toString()方法也会触发懒加载操作,如果代理对象有多个懒加载属性,则调用后面的这四个方法时会同时触发加载所有的懒加载属性。
懒加载操作只会触发一次,下次再调用这些方法时不会再次触发懒加载操作的。
懒加载其实又是一次查询操作,懒加载查询需要传递一些参数,还有一些其他条件。这些待传递的属性、参数、查询所需的 sql 语句等相关的条件都已经封装到了代理对象内部,这些条件封装在一个 Map 中,键是懒加载查询的属性名称,值是查询该属性所需的条件,包括参数、sql 语句等。懒加载完一个属性之后会把这个属性从 Map 中移除,所以再次出发懒加载操作时 mybatis 就知道该属性已经被被加载过了,不会重复加载。
懒加载也是一个挺复杂的过程,我在上面的讲解中省略了很多,要全部讲出来涉及的东西太多。
我再总结一下,懒加载功能使用了代理对象,所以在调用懒加载属性的 get/set 方法(或者是其他触发懒加载操作的方法)时 mybatis 才能知道这时候应该去加载懒加载属性。
ORM 框架hibernate 也是支持lazy 加载的,相信原理也是类似的。
MyBatis:lazy loading的更多相关文章
- Entity Framework Tutorial Basics(37):Lazy Loading
Lazy Loading: One of the important functions of Entity Framework is lazy loading. Lazy loading means ...
- MyBatis Lazy Loading
MyBatis的Lazy Loading可以实现延迟查询Bean里的嵌套成员类,控制lazy loading的<settings>属性有 lazyLoadingEnabled: lazy ...
- Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading
Entity Framework提供了三种加载相关实体的方法:Lazy Loading,Eager Loading和Explicit Loading.首先我们先来看一下MSDN对三种加载实体方法的定义 ...
- 001_Chrome 76支持原生HTML 图片懒加载Lazy loading
Table Of Content 什么是懒加载? 语法参数及使用方式? 有哪些特点? 与js有关的实践 什么是懒加载? 技术背景 Web应用需要经常向后台服务器请求资源(通过查询数据库,是非常耗时耗资 ...
- 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制
你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...
- 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 ...
- EFCore Lazy Loading + Inheritance = 干净的数据表 (二) 【献给处女座的DB First程序猿】
前言 本篇是上一篇EFCore Lazy Loading + Inheritance = 干净的数据表 (一) [献给处女座的DB First程序猿] 前菜 的续篇.这一篇才是真的为处女座的DB Fi ...
- EFCore Lazy Loading + Inheritance = 干净的数据表 (一) 【献给处女座的DB First程序猿】
前言 α角 与 β角 关于α角 与 β角的介绍,请见上文 如何用EFCore Lazy Loading实现Entity Split. 本篇会继续有关于β角的彩蛋在等着大家去发掘./斜眼笑 其他 本篇的 ...
随机推荐
- windows服务器下iis的性能优化 服务器
IIS性能优化 1.调整IIS高速缓存 HKEY_LOCAL_MACHINE SystemCurrentControlSetServicesInetInfoParametersMemoryCacheS ...
- asp .net连接打开数据库初步
1 #endregion59 WebDriver
- Android 异步消息处理机制前篇(一):深入理解ThreadLocal
版权声明:本文出自汪磊的博客,转载请务必注明出处. ThreadLocal简介 ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定线程中可以获 ...
- VUE环境配置——运行Demo
如果有Vue的Demo 不知道怎么运行的同学可以看这里 这里只讲Win下面环境配置 一.NodeJs安装 1.下载Windows 安装包(.msi),并安装https://nodejs.org/d ...
- 配置ssh免密码登陆
以root账户为例 准备两台以上的Linux服务器,我这里用的是s204,s205两台机器,多台同样的 先使用ssh登录试一下,如果没有安装则需要先安装一下 ssh s205会提示你输入密码 原理 ...
- CLR类型设计之方法与构造器
无论学习那门语言都要学习函数体,C#,JAVA,PHP,都会涉及到函数体,而C#的函数体成员并不少,方法和构造器就是函数体成员之一,函数体成员还包括但不限于:方法,属性,构造器,终结器,运算符及索引器 ...
- web前端-----jQuery
web前端之jQuery篇 一 jQuery是什么? [1] jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. [2] j ...
- TweenMax动画库学习
之前在做HTML5移动端开发的时候,用的都是Animate.css,这个插件封装的的确很好,但是在做一些缓动方面的动画,它也有一定的不足之处,比如手要写一个连续的动画,需要不停的去重复写函数,使得代码 ...
- UNIX标准及实现
UNIX标准及实现 引言 在UNIX编程环境和C程序设计语言的标准化方面已经做了很多工作.虽然UNIX应用程序在不同的UNIX操作系统版本之间进行移植相当容易,但是20世纪80年代UNIX版本 ...
- Bash 常用快捷键(转)
在mtysql client中按HOME键和END键失效,查了也没有找到原因 使用Bash常用的快捷方式即可. http://blog.csdn.net/mingzhou/article/detail ...