Mybatis延迟加载、懒加载、二级缓存

DAY22.2 Java核心基础

Mybatis

延迟加载、懒加载

提高程序运行效率的技术

延迟加载,也叫惰性加载或者懒加载

延迟加载如何提升程序的运行效率?

持久层操作有一个原则:Java 程序和数据库交互频率越低越好

Java 程序每次和数据库进行交互,都需要先验证,会消耗资源,所以实际开发中应该尽量减少 Java 程序和数据库的交互次数,从而提高程序的运行效率。

MyBatis 的延迟加载机制,很好的做到了这一点

比如:Class 和 Student 表

当我们查询 Student 对象时,因为有级联关系,所以会将学生对应的班级信息一并查出,等于查了两张表,执行了两条 SQL 语句,分别查询 Class 和 Student

延迟加载的思路:当我们查询 Student 的时候,如果没有访问 Class 属性,则只发送一条 SQL 查询 Student 表,如果需要访问 Class 属性的时候,再发送另一条 SQL,来查询 Class 表。

延迟加载是一种代码优化机制,按需加载,根据具体的代码,来自主选择要发送的 SQL 语句。

比如下面的场景

Student类

java 复制代码
@Data
public class Student  {
    private Integer id;
    private String name;
    private Class clazz;
}

Class类

java 复制代码
@Data
public class Class  {
    private Integer id;
    private String name;
}

StudentMapper接口

java 复制代码
public interface StudentMapper {
    Student getById(Integer id);
}

Mapper的sql映射

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.shuwu.mapper.StudentMapper">

    <resultMap id="studentMap" type="com.shuwu.entity.Student">
        <id property="id" column="id"/>
        <result property="name" column="name"></result>
        <association property="clazz" javaType="com.shuwu.entity.Class" select="com.shuwu.mapper.ClassMapper.getClassById" column="cid">
        </association>
    </resultMap>

    <select id="getById" resultType="com.shuwu.entity.Student" resultMap="studentMap">
        select * from student where id = #{id}
    </select>
</mapper>

Class的sql映射

xml 复制代码
<select id="getClassById" resultType="com.shuwu.entity.Class">
    select * from class where id=#{id}
</select>

配置Mybatis打印sql

xml 复制代码
 <settings>
        <!-- 打印SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING" />
 </settings>

测试类

java 复制代码
public static void main(String[] args) {
    // 找到类加载器,然后创建一个工厂
    InputStream resourceAsStream = Test.class.getClassLoader().getResourceAsStream("com/mybatis-config.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
    // 获取sqlsession
    SqlSession sqlSession = build.openSession();
    // 获取接口的代理对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    System.out.println(mapper.getById(1));
}

可以看见sql执行了两次

但是如果我只需要获取到Student的信息呢,不获取Class的信息

java 复制代码
System.out.println(mapper.getById(1).getName());

可以看见还是执行了两次sql,是不是这里我们可以省略执行class的sql呢

如何实现呢?这就要用到Mybatis的延迟加载机制了,在配置类设置延迟加载即可
xml 复制代码
    <settings>
        <!-- 打印SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING" />
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>

再次运行,发现这次只执行了一次sql

MyBatis 二级缓存

只有在级联查询的时候,Mybatis的延迟加载才有用,如果是单表查询的话我们可以使用二级缓存来优化,解决效率的问题

使用缓存的作用是减少Java程序与数据库的交互次数,提升运行效率,当第一次查出某个对象的时候,Mybatis会这个**对象进行缓存,**当第二次查询的时候就直接从缓存中获取,不需要再次访问数据库

相关推荐
柴薪之王、睥睨众生5 小时前
(自用)Java学习-5.8(总结,springboot)
java·开发语言·spring boot·学习·mybatis
唐僧洗头爱飘柔952716 小时前
【SSM-SSM整合】将Spring、SpringMVC、Mybatis三者进行整合;本文阐述了几个核心原理知识点,附带对应的源码以及描述解析
java·spring·mybatis·springmvc·动态代理·ioc容器·视图控制器
意倾城1 天前
浅说MyBatis-Plus 的 saveBatch 方法
java·mybatis
Brilliant Nemo1 天前
五、框架实战:SSM整合原理和实战
maven·mybatis
小赵面校招1 天前
Spring Boot整合MyBatis全攻略:原理剖析与最佳实践
java·spring boot·mybatis
小赵面校招1 天前
SpringBoot整合MyBatis-Plus:零XML实现高效CRUD
xml·spring boot·mybatis
悟空打码2 天前
MyBatis源码解读5(3.1、缓存简介)
缓存·mybatis
多多*2 天前
Java反射 八股版
java·开发语言·hive·python·sql·log4j·mybatis
Auc242 天前
OJ判题系统第4期之判题机模块架构——设计思路、实现步骤、代码实现(工厂模式、代理模式的实践)
java·spring cloud·log4j·mybatis·代理模式·工厂模式
佛祖让我来巡山2 天前
【Java持久层技术演进全解析】从JDBC到MyBatis再到MyBatis-Plus
mybatis·jdbc·mybatisplus·持久层框架