
Mybatis延迟加载与立即加载
首先看立即加载的日志记录,同时做查询account而不使用account:
@Test
public void testFindAll(){
List<Account> accounts=accountDao.findAll();
}

上面是执行的sql语句。
可以看到在查询account时就把account和所有user查出来了。这就是立即加载。
同样的测试方法,改为延迟加载后:

只查询了account,而没有查询user,这就是延迟加载。
延迟加载有助于节约内存,因为只在使用到具体的关联对象时才查出来,存到内存中。
延迟加载配置准备
先要把account和user都做成单表查询。
如account的findAll
的sql
语句变成了:
<select id="findAll" resultMap="accountMap">
select * from account;
</select>
同时account中保有user属性不变。
延迟加载配置过程
主要是配置association
和 collection
标签中的select
属性。因为这两个标签在不同情况下使用,所以单独来讲。
1. 一对一association
以account对user为例,来看account的xml:
<resultMap id="accountMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--修改为-->
<association property="user" javaType="user" column="uid" select="com.chajiu.dao.IUserDao.findById">
</association>
</resultMap>
意为根据uid再去查找user,将原来的一条sql语句分成了两条
其中
- column:对应主加载对象查出来的字段名
- select:指定该pojo属性从哪个方法中获得
2.一对多collection
以user对account为例,修改IUserDao.xml
配置其实差不多,都是增加了一个column
,和 select
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<result property="birthday" column="birthday"></result>
<collection property="accounts" ofType="account" column="id" select="com.chajiu.dao.IAccountDao.findByUid" >
</collection>
</resultMap>
开启全局延迟
在主配置文件的configuration
中,添加setting
标签
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
配置完成即是按需加载的延迟加载。
延迟加载中的侵入式加载和深度延迟加载
延迟加载,从上面配置的角度来说,是只执行主加载对象的select
语句,而不执行association
和collection
中的select
。
那问题来了,什么时候去加载这些从加载对象呢?
-
访问主加载对象的任何方法,任何属性时就加载它所有从加载对象
也就是去执行从加载对象的那些select方法。这就是侵入式加载
配置方式:
<settings> <!--先开启全局延迟,因为这些都是延迟加载--> <setting name="lazyLoadingEnabled" value="true"/> <!--侵入式延迟加载:设为true--> <setting name="aggressiveLazyLoading" value="true"/> </settings>
-
访问主加载对象的从加载对象时,才去查询
比如,调用account.getUser()时才去查询user信息。这就是深度延迟加载,又叫按需加载
配置方式:
<settings> <!--先开启全局延迟,因为这些都是延迟加载--> <setting name="lazyLoadingEnabled" value="true"/> <!--侵入式延迟加载:设为false,那就是深度延迟加载了--> <setting name="aggressiveLazyLoading" value="true"/> </settings>
fetchType属性
用于指定特殊的从加载对象的加载方式,取值lazy
或 eager
。
lazy
:延迟加载
eager
:立即加载
fetchType
优先级大于上面那个lazyLoadingEnabled
全局延迟加载。
在哪设置呢?
就在association
和collection
那里,如:
<association property="user" javaType="user" column="uid" select="com.chajiu.dao.IUserDao.findById" fetchType="lazy">
</association>
网友评论