美文网首页
Mybatis延迟加载与立即加载

Mybatis延迟加载与立即加载

作者: 茶酒qqq | 来源:发表于2020-02-05 12:09 被阅读0次
image.png

Mybatis延迟加载与立即加载

首先看立即加载的日志记录,同时做查询account而不使用account:

@Test
public void testFindAll(){

   List<Account> accounts=accountDao.findAll();

}
image-20200205105801651.png

上面是执行的sql语句。

可以看到在查询account时就把account和所有user查出来了。这就是立即加载。

同样的测试方法,改为延迟加载后:

image-20200205105930385.png

只查询了account,而没有查询user,这就是延迟加载。

延迟加载有助于节约内存,因为只在使用到具体的关联对象时才查出来,存到内存中。


延迟加载配置准备

先要把account和user都做成单表查询。

如account的findAllsql语句变成了:

<select id="findAll" resultMap="accountMap">
    select * from account;
</select>

同时account中保有user属性不变。


延迟加载配置过程

主要是配置associationcollection标签中的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语句,而不执行associationcollection中的select

那问题来了,什么时候去加载这些从加载对象呢?

  1. 访问主加载对象的任何方法,任何属性时就加载它所有从加载对象

    也就是去执行从加载对象的那些select方法。这就是侵入式加载

    配置方式:

    <settings>
     <!--先开启全局延迟,因为这些都是延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--侵入式延迟加载:设为true-->
        <setting name="aggressiveLazyLoading" value="true"/>
    </settings>
    
  2. 访问主加载对象的从加载对象时,才去查询

    比如,调用account.getUser()时才去查询user信息。这就是深度延迟加载,又叫按需加载

    配置方式:

    <settings>
     <!--先开启全局延迟,因为这些都是延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!--侵入式延迟加载:设为false,那就是深度延迟加载了-->
        <setting name="aggressiveLazyLoading" value="true"/>
    </settings>
    

fetchType属性

用于指定特殊的从加载对象的加载方式,取值lazyeager

lazy:延迟加载

eager:立即加载

fetchType优先级大于上面那个lazyLoadingEnabled全局延迟加载。

在哪设置呢?

就在associationcollection那里,如:

<association property="user" javaType="user" column="uid" select="com.chajiu.dao.IUserDao.findById" fetchType="lazy">
</association>

相关文章

网友评论

      本文标题:Mybatis延迟加载与立即加载

      本文链接:https://www.haomeiwen.com/subject/tctsxhtx.html