mybatis延迟加载

概念

MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询。延迟加载可以有效的减少数据库压力。

延时加载类型及设定

通过对全局参数:lazyLoadingEnabled进行设置,默认就是false。 进行设置修改延时加载状态

直接加载: 执行完对主加载对象的select语句,马上执行对关联对象的select查询。

<settings>
    <!-- 延迟加载总开关 -->
    <setting name="lazyLoadingEnabled" value="false"/>
</settings>
  • 侵入式延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的

某个属性(该属性不是关联对象的属性)时,就会马上执行关联对象的select查询。

<settings>
    <!-- 延迟加载总开关 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 侵入式延迟加载开关 -->
    <setting name="aggressiveLazyLoading" value="true"/>
</settings>
  • **深度延迟:**执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询。
<settings>
    <!-- 延迟加载总开关 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 侵入式延迟加载开关 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  • 优缺点

    • 深度延迟加载的使用会提升性能。

    • 如果延迟加载的表数据太多,此时会产生N+1问题,主信息加载一次算1次,而从信息是会根据主

      信息传递过来的条件,去查询从表多次。

延时加载实例

需要校验的是 深度延迟的时候直接调用bankCardList是否有问题

​ 首先我们先思考一个问题,假设:在一对多中,我们有一个用户,他有10张银行卡。

问题1:在查询用户的时候,要不要把关联的银行卡查出来?

问题2:在查询银行卡的时候,要不要把关联的用户查出来?

  • 用户类及银行卡类

    public class User implements Serializable{
        private Integer id;
        private String username;
        private Date birthday;
        private String sex;
        private String address;
        private List<BankCard> cardList;
    
        get和set方法省略.....      
    }
    
    
    public class BankCard implements Serializable{
        private Integer id;
        private Integer uid;
        private String cardNo;
    
        get和set方法省略.....      
    }
    
  • dao层接口

    /**
         * 查询所有的用户
         *
         * @return
         */
        List<User> findAll();
    
    
    
  • xml配置

    <resultMap id="userAccountMap" type="com.example.domain.User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="birthday" column="birthday"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <collection property="bankCardList" ofType="com.example.domain.BankCard" column="id"
                    select="com.example.dao.BankCardDao.findAllByUid"/>
    resultMap>
    <select id="findAll" resultMap="userAccountMap">
        SELECT * FROM USER;
    select>
    

**注意:**主要的功能实现位于中,对于银行卡列表的信息通过collection集合来映射,通过select指定集合中的每个元素如何查询,在本例中select的属性值为BankCardDao.xml文件的namespace com.example.dao.AccountDao路径以及指定该映射文件下的findAllByUid方法,通过这个唯一标识指定集合中元素的查找方式。因为在这里需要用到根据用户ID查找账户,所以需要同时配置一下findAllByUid方法的实现。

  • BankCardDao的实现

     /**
         * 根据用户ID查询账户信息
         * @return
         */
        List<BankCard> findAllByUid(Integer uid);
    
    
  • BankCardDao.xml

     
    <select id="findAllByUid" resultType="com.example.domain.BankCard">
            SELECT * FROM bank_card WHERE uid = #{uid};
     select>
    
    
  • mybatis开启全局延迟加载配置

    configuration>
        <settings>
            
            <setting name="lazyLoadingEnabled" value="true"/>
            
            <setting name="aggressiveLazyLoading" value="false"/>
            
            <setting name="logImpl" value="STDOUT_LOGGING" />
        settings>
    
    
        <typeAliases>
            <typeAlias type="com.example.domain.Account" alias="account"/>
            <typeAlias type="com.example.domain.User" alias="user"/>
            <package name="com.example.domain"/>
        typeAliases>
    
    
        <environments default="test">
            <environment id="test">
                
                <transactionManager type="jdbc">transactionManager>
                
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/test1"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                dataSource>
            environment>
        environments>
        
        <mappers>
            <mapper resource="com/example/dao/UserDao.xml"/>
            <mapper resource="com/example/dao/AccountDao.xml"/>
        mappers>
    configuration>
    

你可能感兴趣的:(mybatis)