5. MyBatis延迟加载

5.1 什么是延迟加载

resultMap可以实现高级映射(使用association、collection实现一对一及一对多映射),association、collection具备延迟加载功能。

需求:

如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。

延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高 数据库性能,因为查询单表要比关联查询多张表速度要快。


5.2 使用association实现延迟加载

image.png

5.2.1 需求

查询订单并关联用户信息

5.2.2 mapper.xml

需要定义两个mapper的方法对应的statement。
1)只查询订单信息

    select * from emp;
    在查询订单的statement中使用association去延迟加载(执行)下边的satatement(关联查询用户信息)
    
    

2)关联查询部门信息

 通过上面查询的部门编码dept_id去关联查询部门信息
    

上边先去执行findEmpLazyLoading,当需要去查询用户的时候再去执行findEmpById,通过resultMap的定义将延迟加载执行配置起来。

5.2.3 延迟加载resultMap

使用association中的select指定延迟加载去执行的statement的id。

    
    
         
         
         
         
         
         
    
         
         
    

Empmapper.xml




    
    
         
         
         
         
         
    
    
    

实现类:EmpDaoImpl.java

package com.demo.dao.imp;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.demo.entity.Emp;
import com.demo.util.MyBatisUtil;
public class EmpDaoImpl {
    SqlSession session;
        public List findEmpLazyLoading() {
            // TODO Auto-generated method stub
            List emps =null;
            try {
                session = MyBatisUtil.getSession();    
                emps = session.selectList("com.demo.entity.EmpMapper.findEmpDeptLazyLoading");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace()
            }finally{
                try {
                    MyBatisUtil.closeSession();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return emps;
        }
}

5.3 测试

5.3.1 测试思路:

1、执行上边mapper方法(findOrdersUserLazyLoading),内部去调用cn.itcast.mybatis.mapper.OrdersMapperCustom中的findOrdersUserLazyLoading只查询orders信息(单表)。
2、在程序中去遍历上一步骤查询出的List,当我们调用Orders中的getUser方法时,开始进行延迟加载。
3、延迟加载,去调用UserMapper.xml中findUserbyId这个方法获取用户信息。

5.3.2 延迟加载配置

mybatis默认没有开启延迟加载,需要在SqlMapConfig.xml中setting配置。
在mybatis核心配置文件中配置:
lazyLoadingEnabled、aggressiveLazyLoading


image.png

在config.xml中配置:

    
    
    
    
         
         
         
         
    

5.3.3 测试代码 TestEmpMapDept.java

package com.demo.test;
import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.demo.dao.imp.EmpDaoImpl;
import com.demo.entity.Dept;
import com.demo.entity.Emp;
public class TestEmpMapDept {
    private static EmpDaoImpl empDaoImpl;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        empDaoImpl = new EmpDaoImpl();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        empDaoImpl = null;
    }

    // 查询订单关联查询用户,用户信息使用延迟加载
    @Test
    public void testFindEmpLazyLoading() throws Exception {
        // 查询员工信息(单表)
        List list = empDaoImpl.findEmpLazyLoading();
        // 遍历上边的员工列表
        for (Emp emp : list) {
            //System.out.println(emp.getDeptId());
            Dept dept = emp.getDept();
            System.out.println(dept);
        }
    }
}

测试效果:


image.png

5.3.4 延迟加载思考

不使用mybatis提供的association及collection中的延迟加载功能,如何实现延迟加载?
实现方法如下:
定义两个mapper方法:
1、查询订单列表
2、根据用户id查询用户信息

实现思路:
先去查询第一个mapper方法,获取订单信息列表
在程序中(service),按需去调用第二个mapper方法去查询用户信息。

总之:
使用延迟加载方法,先去查询简单的sql(最好单表,也可以关联查询),再去按需要加载关联查询的其它信息。

你可能感兴趣的:(5. MyBatis延迟加载)