mybatis association 懒加载实现原理

来源:互联网 发布:2016华为云计算大会 编辑:程序博客网 时间:2024/05/16 05:45

前言

mybatis的association 标签可以设置关联对象,加载方式;如下的user关联dept,加载方式fetchType=”eager”

 <resultMap id="BaseResultMap" type="testmaven.entity.User">    <id column="id" jdbcType="INTEGER" property="id" />    <result column="dept_id" jdbcType="INTEGER" property="deptId" />    <association property="dept" column="dept_id" fetchType="eager" select="testmaven.mapper.DeptMapper.selectByPrimaryKey" ></association>  </resultMap>

以上的配置、意义咱们都知道。但是这里有两个问题,第一,主数据以什么方式获取的关联对象,是两个表关联查询的还是获取主数据后一条一条的查询的从数据,如果是这样那么就会存在N+1的问题?再就是,懒加载时,只有用到主数据时,才会查询关联数据,那么这个“用到”是什么意思?


关联数据获取的原理

association数据的获取,都是先获取主数据,然后根据主数据的某些字段获取关联数据,是一条条查询的,并不是多表关联查询的,这种方式存在查询N+1问题,具体到加载方式又有些不同

eager

query主数据时,会立刻query关联数据,这两个query使用的同一个jdbc connection。

lazy

query主数据库时,不会query关联数据,只有在调用主数据的方法时,才会query获取数据(比如例中user.toString()、user.getName()等方法),这两个query使用不同connection

到这里,第一个问题,解决了,继续往下看。

懒加载的实现原理

经过debug发现,在执行主数据的方法时(user.toString()、user.getName()),才会获取数据。mybatis怎么实现的?原来mapper返回的类是代理类,mybatis使用javassist技术创建代理类,然后代理类任何方法都会调用JavassistProxyFactory$EnhancedResultObjectProxyImpl 的invoke方法,在invoke方法中获取关联数据,从而实现了懒加载!

图1
这里写图片描述

图2
这里写图片描述

图3
这里写图片描述

更深层次的研究,打算将代理类输出到磁盘,反编译查看它的源码,这部分在研究javassist后再来补充。

0 0
原创粉丝点击