Mybatis学习笔记(十一)——延迟加载

本博客源码下载:戳我一下

Mybatis学习笔记汇总:戳我一下

一、什么是延迟加载

resultMap可以实现高级映射(使用associationcollection实现一对一、一对多和多对多映射),associationcollection具备延迟加载功能。
需求:
如果查询订单并且关联查询用户信息。如果先查询订单信息即可满足要求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需去查询就是延迟加载。

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

二、使用association实现延迟加载(使用collection的方法和这个类似)

1、配置Mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jiayifan.mapper.LazyLoadMapper">
    <!-- 延迟加载的resultMap -->
    <resultMap type="com.jiayifan.po.Orders" id="OrdersUserLazyLoadingResultMap">
            <!--对订单信息进行映射配置  -->
            <id column="id" property="id"/>
            <result column="user_id" property="userId"/>
            <result column="number" property="number"/>
            <result column="createtime" property="createtime"/>
            <result column="note" property="note"/>
            <!-- 实现对用户信息进行延迟加载
            select:指定延迟加载需要执行的statement的id(是根据user_id查询用户信息的statement)
            要使用userMapper.xml中findUserById完成根据用户id(user_id)用户信息的查询,如果findUserById不在本mapper中需要前边加namespace
            column:订单信息中关联用户信息查询的列,是user_id
            关联查询的sql理解为:
            SELECT orders.*,
    (SELECT username FROM USER WHERE orders.user_id = user.id)username,
    (SELECT sex FROM USER WHERE orders.user_id = user.id)sex
     FROM orders
             -->
            <association property="user"  javaType="com.jiayifan.po.User"
             select="com.jiayifan.mapper.UserMapper.findUserById" column="user_id">
            <!-- 实现对用户信息进行延迟加载 -->

            </association>

    </resultMap>
    <select id="findOrdersLazyLoad" resultMap="OrdersUserLazyLoadingResultMap">
        SELECT
        orders.*
        FROM
        orders
    </select>
</mapper>

2、Mapper接口

public List<Orders> findOrdersLazyLoad() throws Exception;

3、延迟加载配置
mybatis默认没有开启延迟加载,需要在SqlMapConfig.xmlsetting配置。

mybatis核心配置文件中配置:

<!-- 全局参数配置 -->
    <settings>
        <!-- 打开延迟加载的开关 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 将积极加载改为消极加载 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
设置项描述允许值默认值
lazyLoadingEnabled全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。true or falsefalse
aggressiveLazyLoading当设置为‘true’的时候,懒加载的对象可能被任何懒属性全部加载。否则,每个属性都按需加载。true or falsetrue

4、测试思路和测试代码
(1)执行mapper方法(findOrdersLazyLoad),内部去调用中的com.jiayifan.mapper.UserMapper.findUserByIdfindOrdersLazyLoad只查询orders信息(单表)。

(2)在程序中去遍历上一步骤查询出的List<Orders>,当我们调用Orders中的getUser方法时,开始进行延迟加载。

(3)延迟加载,去调用UserMapper.xmlfindUserbyId这个方法获取用户信息。

package com.jiayifan.mapper;

import static org.junit.jupiter.api.Assertions.*;

import java.io.InputStream;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.jiayifan.po.Orders;

class lazyLoadTest {

    private SqlSessionFactory sqlSessionFactory;
    @BeforeEach
    void setUp() throws Exception {
        //创建SqlSessionFactory
        //Mybatis的配置文件
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //创建会话工厂
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    void testFindOrdersLazyLoad() throws Exception {
        //获取session
        SqlSession session = sqlSessionFactory.openSession();
        //获限mapper接口实例
        LazyLoadMapper lazyLoadMapper = session.getMapper(LazyLoadMapper.class);
        List<Orders> list = lazyLoadMapper.findOrdersLazyLoad();
        for(Orders order : list) {
            System.out.println(order);
        }
        session.close();
    }

}

我们如果采用debug方法运行程序,我们可以看到延迟加载发生了,程序先发送了查询单表的sql语句,在需要采用多表查询的时候才发送查询多表的sql语句

三、延迟加载思考

不使用mybatis提供的associationcollection中的延迟加载功能,如何实现延迟加载:

实现方法如下:
定义两个mapper方法:
1、查询订单列表
2、根据用户id查询用户信息
实现思路:
先去查询第一个mapper方法,获取订单信息列表
在程序中(service层),按需去调用第二个mapper方法去查询用户信息。
总之:
使用延迟加载方法,先去查询简单的sql(最好单表,也可以关联查询),再去按需要加载关联查询的其它信息。

四、延迟加载总结

作用:
当需要查询关联信息时再去数据库查询,默认不去关联查询,提高数据库性能。
只有使用resultMap支持延迟加载设置。
场合:
当只有部分记录需要关联查询其它信息时,此时可按需延迟加载,需要关联查询时再向数据库发出sql,以提高数据库性能。
当全部需要关联查询信息时,此时不用延迟加载,直接将关联查询信息全部返回即可,可使用resultTyperesultMap完成映射。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页