懒加载的原理

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的更多相关文章

  1. Entity Framework Tutorial Basics(37):Lazy Loading

    Lazy Loading: One of the important functions of Entity Framework is lazy loading. Lazy loading means ...

  2. MyBatis Lazy Loading

    MyBatis的Lazy Loading可以实现延迟查询Bean里的嵌套成员类,控制lazy loading的<settings>属性有 lazyLoadingEnabled: lazy ...

  3. Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading

    Entity Framework提供了三种加载相关实体的方法:Lazy Loading,Eager Loading和Explicit Loading.首先我们先来看一下MSDN对三种加载实体方法的定义 ...

  4. 001_Chrome 76支持原生HTML 图片懒加载Lazy loading

    Table Of Content 什么是懒加载? 语法参数及使用方式? 有哪些特点? 与js有关的实践 什么是懒加载? 技术背景 Web应用需要经常向后台服务器请求资源(通过查询数据库,是非常耗时耗资 ...

  5. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  6. Lazyr.js – 延迟加载图片(Lazy Loading)

    Lazyr.js 是一个小的.快速的.现代的.相互间无依赖的图片延迟加载库.通过延迟加载图片,让图片出现在(或接近))视窗才加载来提高页面打开速度.这个库通过保持最少选项并最大化速度. 在线演示    ...

  7. Can you explain Lazy Loading?

    Introduction Lazy loading is a concept where we delay the loading of the object until the point wher ...

  8. EFCore Lazy Loading + Inheritance = 干净的数据表 (二) 【献给处女座的DB First程序猿】

    前言 本篇是上一篇EFCore Lazy Loading + Inheritance = 干净的数据表 (一) [献给处女座的DB First程序猿] 前菜 的续篇.这一篇才是真的为处女座的DB Fi ...

  9. EFCore Lazy Loading + Inheritance = 干净的数据表 (一) 【献给处女座的DB First程序猿】

    前言 α角 与 β角 关于α角 与 β角的介绍,请见上文 如何用EFCore Lazy Loading实现Entity Split. 本篇会继续有关于β角的彩蛋在等着大家去发掘./斜眼笑 其他 本篇的 ...

随机推荐

  1. ASP.NET没有魔法——ASP.NET MVC Controller的实例化与执行

    上一章节中对路由的注册和匹配过程进行了介绍,知道了MVC的Http请求最终是交由MvcHandler处理的,而其处理过程就是对Controller的创建.执行和释放. 本章将从以下几点进一步对上面提到 ...

  2. Python 简单理解多线程

    进程,是一个或多个线程的集合,每个进程在内存中是相对独立的. 线程,是计算机最小的运算单元,每个进程至少要有一个线程,多个线程时,每个线程间之间共享内存. 分别举例常规运行和多线程运行: 0)常规运行 ...

  3. android studio 默认 .gitignore 文件模板

    # built application files*.apk*.ap_ # files for the dex VM*.dex # Java class files*.class # generate ...

  4. Bin、App_Data等文件夹详述(转自http://blog.csdn.net/zzjiadw/article/details/6801506)

    ASP.NET应用程序和ASP.Net网站所共有的文件: App_Browsers 包含 ASP.NET 用于标识个别浏览器并确定其功能的浏览器定义 (.browser) 文件.有关更多信息,请参见浏 ...

  5. 二叉树、栈、队列、链表的Java代码实现

    这是我的学习总结. 如有文章存在谬误,欢迎指出,有其他意见或者建议,也欢迎留言 二叉树链表 前序遍历:先访问根节点,然后访问左子树.右子树 中序遍历:先访问左子树,然后访问根节点.右子树 后序遍历:先 ...

  6. python之列表(list)的使用方法介绍

    python之列表(list)介绍 在python的使用过程中,我们经常会用到列表,然而经常会遇到疑惑,下面我将详细介绍下列表使用方法. 一.列表 列表经常用到的功能使增.删.改和查功能. 1. 增 ...

  7. Nginx简介与安装

    | 简介 Nginx是一个高性能的HTTP和反向代理服务器,可以作为负载均衡服务器,也是一个IMAP/POP3/SMTP服务器.它的特点是占有内存少,并发能力强.目前有很多大型公司都在使用Nginx, ...

  8. c# AutoMapper 使用方式

    安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可. 我从网上找了一些资料,下载了个demo,然后自己又写了一遍,我把AutoMapper 的使用分为 ...

  9. python解释执行原理(转载)

    Python解释执行原理 转自:http://l62s.iteye.com/blog/1481421 这里的解释执行是相对于编译执行而言的.我们都知道,使用C/C++之类的编译性语言编写的程序,是需要 ...

  10. spring bean的创建过程

    spring的核心容器包括:core.beans.context.express language四个模块.所以对于一个简单的spring工程,最基本的就是依赖以下三个jar包即可: <depe ...