2024年 Java 面试八股文——Mybatis篇

目录

[1. 什么是Mybatis?](#1. 什么是Mybatis?)

[2. 说说Mybatis的优缺点](#2. 说说Mybatis的优缺点)

[3. Xml映射文件中,都有哪些标签](#3. Xml映射文件中,都有哪些标签)

4. #{}和&{}有什么区别

[5. Mybatis是如何进行分页的,分页插件的原理是什么](#5. Mybatis是如何进行分页的,分页插件的原理是什么)

[6. Mybatis是如何将sql执行结果封装为目标对象并返回的?](#6. Mybatis是如何将sql执行结果封装为目标对象并返回的?)

[7. Mybatis是怎么将mapper与xml联系起来的](#7. Mybatis是怎么将mapper与xml联系起来的)

[8. 如何执行批量插入(SqlSessionFactory)](#8. 如何执行批量插入(SqlSessionFactory))

[9. Mybatis通过jdk动态代理的原理](#9. Mybatis通过jdk动态代理的原理)

[10. Mybatis的工作原理(重要)](#10. Mybatis的工作原理(重要))

[11. Mybatis实现一对一、一对多有几种方式](#11. Mybatis实现一对一、一对多有几种方式)

[12. Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?](#12. Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?)

[13. 说说Mybatis的缓存机制](#13. 说说Mybatis的缓存机制)


MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通的 Java 对象)为数据库中的记录。

1. 什么是Mybatis?

Mybatis是持久层框架,半自动ORM框架,对JDBC操作数据库的过程进行了封装,使得开发者只需要关注sql本身。

JDBC操作数据库:加载JDBC驱动程序、提供JDBC连接的URL 、创建数据库的连接connection 、创建一个Statement、执行SQL语句、处理结果、关闭JDBC对象

2. 说说Mybatis的优缺点

MyBatis 作为一个优秀的持久层框架,具有许多优点,但同时也存在一些潜在的缺点。以下是 MyBatis 的主要优缺点概述:

优点

  1. 灵活性:MyBatis 提供了非常灵活的方式来映射 SQL 语句到 Java 对象。通过 XML 配置文件或注解,你可以精确地控制 SQL 语句的生成,这使得在复杂或特定需求的场景中能够编写出精确的 SQL 语句。

  2. 避免 JDBC 编码:MyBatis 封装了 JDBC 的底层实现,开发者无需再编写大量的 JDBC 代码,如设置参数、处理结果集等,这大大减少了代码量,提高了开发效率。

  3. 动态 SQL:MyBatis 提供了强大的动态 SQL 功能,允许你根据参数的不同动态地生成 SQL 语句。这使得在构建复杂查询时更加灵活和方便。

  4. 解耦:MyBatis 将 SQL 语句从 Java 代码中分离出来,放在 XML 配置文件中,这使得代码更加清晰、易于维护。同时,这也使得数据库层的修改可以独立于应用层进行。

  5. 插件机制:MyBatis 提供了插件机制,允许你编写自定义的插件来拦截和修改 SQL 语句的执行过程。这为扩展 MyBatis 的功能提供了很大的便利。

  6. 良好的性能:MyBatis 在处理大量数据时仍然能够保持较高的性能。它提供了缓存机制来缓存查询结果,避免重复执行相同的 SQL 语句。

缺点

  1. SQL 语句编写:虽然 MyBatis 提供了灵活的方式来映射 SQL 语句,但这也要求开发者具备一定的 SQL 编写能力。如果 SQL 语句编写不当,可能会影响性能或引发错误。

  2. XML 配置文件:MyBatis 的配置主要基于 XML 文件,这增加了配置文件的复杂性和维护成本。对于不熟悉 XML 的开发者来说,可能会感到有些困难。

  3. 错误处理:MyBatis 没有提供完整的错误处理机制。当 SQL 语句执行出错时,通常需要开发者自行处理错误并给出相应的提示。

  4. 学习曲线:对于初学者来说,MyBatis 的学习曲线可能比较陡峭。需要了解 MyBatis 的核心概念、配置方式、映射规则等。

  5. 与 ORM 框架的对比:与一些 ORM(对象关系映射)框架相比,MyBatis 需要手动编写 SQL 语句,这可能会增加一些工作量。ORM 框架通常能够自动处理数据库表与 Java 对象之间的映射关系,但在某些复杂场景下可能不够灵活。

  6. 依赖数据库:MyBatis 的 SQL 语句是针对特定数据库的,如果更换数据库,可能需要修改大量的 SQL 语句和映射配置。这增加了迁移数据库的难度。

3. Xml映射文件中,都有哪些标签

  1. <mapper> :这是 XML 映射文件的根元素。它通常包含一个 namespace 属性,该属性指向映射文件对应的接口全限定路径。

  2. <select>:用于映射查询操作,包含 SELECT SQL 语句。

  3. <insert>:映射插入操作,包含 INSERT SQL 语句。

  4. <update>:映射更新操作,包含 UPDATE SQL 语句。

  5. <delete>:映射删除操作,包含 DELETE SQL 语句。

  6. <resultMap> :定义结果集映射规则,将数据库查询结果与 Java 对象属性进行映射。它通常包含 <id><result><association><collection> 等子标签。

  7. <sql> :定义可重用的 SQL 片段,可以被其他语句引用。然后通过 <include> 标签引入这个 SQL 片段。

  8. <include>:用于引用已定义的 SQL 片段。

  9. <selectKey>:用于在插入操作后获取生成的主键值,通常用于不支持自增主键的数据库。

  10. 动态 SQL 标签 :这些标签用于构建动态 SQL 语句,可以根据条件参数动态生成不同的 SQL。包括 <if><choose><when><otherwise><where><set><foreach> 等。

    • <if>:根据条件包含或排除 SQL 片段。
    • <choose><when><otherwise>:类似于 Java 中的 switch-case 结构,根据条件选择执行不同的 SQL 片段。
    • <where>:用于简化 WHERE 子句的构建,自动去除多余的"AND"或"OR"关键字。
    • <set>:用于更新语句中动态包含需要更新的字段,同样可以自动去除多余的逗号。
    • <foreach>:用于遍历集合或数组,并构建 SQL 语句的 IN 条件等。
  11. <cache>:用于配置二级缓存。

4. #{}和&{}有什么区别

  1. #{}是预编译处理,${}是字符串替换
  2. 处理#{}时,会将sql中的#{}替换为?号,调用预编译PreparedStatement 的set方法来赋值
  3. 处理时${}时,就是把{}替换成变量的值
  4. #{}可以防止 SQL 注入,安全

5. Mybatis是如何进行分页的,分页插件的原理是什么

MyBatis 提供了两种主要的分页方式:逻辑分页和物理分页。但通常我们讨论的是物理分页,因为它更加高效。

MyBatis 的物理分页

物理分页是通过在 SQL 语句中添加 LIMITOFFSET 子句来实现的。MyBatis 并没有直接提供物理分页的内置支持,但我们可以使用 MyBatis 的插件机制来扩展其功能,实现物理分页。

分页插件的原理

分页插件(如 PageHelper)的原理主要基于 MyBatis 的拦截器(Interceptor)机制。以下是分页插件的基本工作原理:

  1. 配置插件 :在 MyBatis 的配置文件(如 mybatis-config.xml)中配置分页插件,并设置相关参数,如数据库方言、分页参数等。
  2. 拦截 SQL 语句 :当 MyBatis 执行查询操作时,分页插件会拦截 SQL 语句。这通常是通过实现 MyBatis 的 Interceptor 接口,并在 intercept 方法中完成拦截的。
  3. 修改 SQL 语句 :分页插件会分析拦截到的 SQL 语句,并根据分页参数(如当前页码、每页显示数量)来修改 SQL 语句。具体来说,插件会在 SQL 语句的末尾添加 LIMITOFFSET 子句,以实现分页功能。
  4. 执行修改后的 SQL 语句:分页插件将修改后的 SQL 语句返回给 MyBatis,然后由 MyBatis 执行该 SQL 语句,并返回结果。
  5. 处理结果:MyBatis 将查询结果封装成 List 或其他形式,并返回给调用者。分页插件可能还需要对返回的结果进行处理,如计算总页数等。

注意事项

  • 性能考虑:在使用物理分页时,应尽量减少每页显示的记录数,以减少数据库查询的压力。
  • 插件选择:除了 PageHelper 之外,还有其他一些分页插件可供选择,如 MyBatis-Plus 的内置分页功能等。在选择插件时,应根据项目需求和团队习惯进行选择。
  • 配置参数:在使用分页插件时,应仔细配置相关参数,以确保插件能够正常工作。例如,需要正确设置数据库方言、分页参数等。
  • 兼容性:不同的分页插件可能具有不同的兼容性和限制。在使用插件之前,应仔细阅读文档并了解插件的兼容性和限制情况。

分页插件步骤:

项目中引入 PageHelper 的依赖。如果你使用 Maven,可以在 pom.xml 文件中添加以下依赖:

java 复制代码
<dependency>  
    <groupId>com.github.pagehelper</groupId>  
    <artifactId>pagehelper-spring-boot-starter</artifactId>  
    <version>你的PageHelper版本号</version>  
</dependency>

请注意将 你的PageHelper版本号 替换为当前可用的最新版本号。

MyBatis 配置文件(如 mybatis-config.xml)或者 Spring Boot 项目的配置文件中(如 application.propertiesapplication.yml)不需要特别的配置(如果使用了 Spring Boot starter 的话)。

使用 PageHelper 进行分页的 Java 代码示例:

java 复制代码
import com.github.pagehelper.Page;  
import com.github.pagehelper.PageHelper;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Service;  
  
import java.util.List;  
  
@Service  
public class YourService {  
  
    @Autowired  
    private YourMapper yourMapper; // 假设这是你的 MyBatis Mapper 接口  
  
    public Page<YourEntity> findYourEntitiesByPage(int pageNum, int pageSize) {  
        // 设置分页信息,注意这里 pageNum 和 pageSize 的值是从 1 开始的,不是从 0 开始  
        PageHelper.startPage(pageNum, pageSize);  
          
        // 接下来执行的查询会进行分页,注意这里的查询语句会被 PageHelper 拦截并处理  
        List<YourEntity> list = yourMapper.selectYourEntities();  
          
        // 使用 Page 对象包装查询结果,Page 对象包含了当前页数据、总页数、总记录数等信息  
        Page<YourEntity> page = (Page<YourEntity>) list;  
          
        // 返回分页数据  
        return page;  
    }  
}

6. Mybatis是如何将sql执行结果封装为目标对象并返回的?

1. 使用resultMap标签

使用resultMap标签,做java对象名和数据库列名映射

2. 数据库别名

使用数据库别名

7. Mybatis是怎么将mapper与xml联系起来的

MyBatis 将 Mapper 接口与 XML 映射文件联系起来的原理主要依赖于 JDK 动态代理技术和 MyBatis 的内部实现机制。以下是具体的过程:

  1. Mapper 接口定义:首先,你需要定义一个 Mapper 接口,这个接口中包含了与数据库操作相关的方法。
  2. XML 映射文件 :然后,你需要编写一个与 Mapper 接口对应的 XML 映射文件(通常以 .xml 为后缀)。这个文件包含了具体的 SQL 语句、参数类型、结果映射等信息。在 XML 文件中,<mapper> 标签的 namespace 属性通常设置为 Mapper 接口的全限定名,这样 MyBatis 就能知道这个 XML 文件是为哪个 Mapper 接口服务的。
  3. Mapper 代理类的生成:当 MyBatis 启动或 Mapper 接口被加载时,MyBatis 会使用 JDK 动态代理技术为这个 Mapper 接口生成一个代理类(通常是 MapperProxy)。这个代理类实现了 Mapper 接口,并拦截了接口中所有方法的调用。
  4. 方法调用与 SQL 执行:当应用程序调用 Mapper 接口中的方法时,实际上是在调用 Mapper 代理类的方法。Mapper 代理类会拦截这个方法的调用,并根据方法的名称和参数信息,在 XML 映射文件中找到对应的 SQL 语句。然后,MyBatis 会创建一个 SqlSession 对象,并将方法名和参数传递给 SqlSession 对象。SqlSession 对象会根据 XML 映射文件中的配置,解析 SQL 语句,设置参数,并执行 SQL 语句。
  5. 结果处理 :执行完 SQL 语句后,SqlSession 对象会将查询结果返回给 Mapper 代理类。Mapper 代理类会根据 XML 映射文件中的结果映射规则(如 <resultMap> 标签),将查询结果转换成 Java 对象,并返回给应用程序。

8. 如何执行批量插入(SqlSessionFactory)

在 MyBatis 中执行批量插入通常涉及到 SqlSession 的使用,而不是直接使用 SqlSessionFactorySqlSessionFactory 是用于创建 SqlSession 的工厂类,而 SqlSession 是执行 SQL 语句的接口。

以下是如何使用 MyBatis 执行批量插入的步骤:

  1. 配置 MyBatis :确保你的 MyBatis 配置文件(如 mybatis-config.xml)和 Mapper XML 文件已经正确配置。
  2. 获取 SqlSessionFactory :从 MyBatis 配置文件中获取 SqlSessionFactory
  3. 打开 SqlSession :使用 SqlSessionFactory 打开一个新的 SqlSession
  4. 执行批量插入
    • 使用 Mapper 接口中的方法执行多次插入(如果 Mapper 方法支持批量插入)。
    • 或者,手动构建批量插入的 SQL 语句,并使用 SqlSessioninsert() 方法执行。
  5. 提交事务:确保在批量插入后提交事务。
  6. 关闭 SqlSession :在完成所有操作后关闭 SqlSession

示例代码:

使用 MyBatis 执行批量插入的示例:

UserMapper.java
java 复制代码
public interface UserMapper {  
    // 通常 Mapper 接口中不会有直接的批量插入方法,但你可以定义一个方法来执行自定义的 SQL  
    int batchInsertUsers(List<User> users);  
}

UserMapper.xml

java 复制代码
<mapper namespace="com.example.mapper.UserMapper">  
    <!-- 假设你有一个批量插入的 SQL 语句 -->  
    <insert id="batchInsertUsers" parameterType="list">  
        INSERT INTO users (column1, column2, ...)  
        VALUES   
        <foreach collection="list" item="user" separator=",">  
            (#{user.property1}, #{user.property2}, ...)  
        </foreach>  
    </insert>  
</mapper>

执行批量插入

java 复制代码
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {  
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  
    List<User> users = ... // 填充用户列表  
  
    // 假设 batchInsertUsers 是你的批量插入方法  
    userMapper.batchInsertUsers(users);  
  
    // 提交事务  
    sqlSession.commit();  
}

9. Mybatis通过jdk动态代理的原理

MyBatis 通过 JDK 动态代理实现 Mapper 接口与 SQL 语句之间的关联,其原理步骤:

  1. Mapper 接口定义
    • 开发者定义 Mapper 接口,该接口中包含了与数据库操作相关的方法。
  2. XML 映射文件
    • 开发者为每个 Mapper 接口编写对应的 XML 映射文件,文件中定义了 SQL 语句、参数类型、结果映射等信息。
    • XML 映射文件的 <mapper> 标签的 namespace 属性设置为 Mapper 接口的全限定名,这样 MyBatis 就知道这个 XML 文件是为哪个 Mapper 接口服务的。
  3. SqlSessionFactory 与 SqlSession
    • MyBatis 通过 SqlSessionFactoryBuilder 加载配置文件(如 mybatis-config.xml),然后创建 SqlSessionFactory。
    • SqlSessionFactory 负责创建 SqlSession,SqlSession 是执行 SQL 语句的接口。
  4. JDK 动态代理
    • 当应用程序通过 SqlSession 调用 Mapper 接口中的方法时,MyBatis 不会直接执行这些方法。
    • 相反,MyBatis 使用 JDK 动态代理为 Mapper 接口生成一个代理对象(MapperProxy)。
    • 这个代理对象实现了 Mapper 接口,并拦截了接口中所有方法的调用。
  5. 方法调用与 SQL 执行
    • 当应用程序调用 Mapper 接口中的方法时,实际上是调用了 Mapper 代理对象(MapperProxy)的方法。
    • Mapper 代理对象会根据方法的名称和参数信息,在 XML 映射文件中找到对应的 SQL 语句。
    • 然后,Mapper 代理对象会创建一个 SqlCommand 对象(包含 SQL 语句、参数等信息),并将其传递给 SqlSession 执行。
  6. 结果处理
    • SqlSession 执行 SQL 语句后,会将查询结果返回给 Mapper 代理对象。
    • Mapper 代理对象会根据 XML 映射文件中的结果映射规则(如 <resultMap>),将查询结果转换成 Java 对象,并返回给应用程序。
  7. 事务管理
    • MyBatis 支持事务管理,可以在 SqlSession 级别控制事务的提交和回滚。
    • 开发者可以通过 SqlSession 的 commit()rollback() 方法来管理事务。

演示如何通过 JDK 动态代理实现 Mapper 接口与 SQL 语句之间的关联:

1. Mapper 接口定义

java 复制代码
package com.example.mapper;  
  
import com.example.model.User;  
  
public interface UserMapper {  
    User selectUserById(int id);  
    void insertUser(User user);  
    // ... 其他方法 ...  
}

2. XML 映射文件

java 复制代码
<?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.example.mapper.UserMapper">  
    <select id="selectUserById" resultType="com.example.model.User">  
        SELECT * FROM users WHERE id = #{id}  
    </select>  
    <insert id="insertUser" parameterType="com.example.model.User">  
        INSERT INTO users (name, age) VALUES (#{name}, #{age})  
    </insert>  
    <!-- ... 其他 SQL 语句 ... -->  
</mapper>
  1. MyBatis 配置文件
java 复制代码
<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">  
<configuration>  
    <environments default="development">  
        <environment id="development">  
            <transactionManager type="JDBC"/>  
            <dataSource type="POOLED">  
                <!-- 数据库连接信息 -->  
                <property name="driver" value="com.mysql.jdbc.Driver"/>  
                <property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/>  
                <property name="username" value="root"/>  
                <property name="password" value="password"/>  
            </dataSource>  
        </environment>  
    </environments>  
    <mappers>  
        <mapper resource="com/example/mapper/UserMapper.xml"/>  
        <!-- ... 其他映射文件 ... -->  
    </mappers>  
</configuration>

4. SqlSessionFactory 与 SqlSession

java 复制代码
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 java.io.IOException;  
import java.io.Reader;  
  
public class MyBatisDemo {  
    public static void main(String[] args) {  
        String resource = "mybatis-config.xml";  
        try (Reader reader = Resources.getResourceAsReader(resource)) {  
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);  
              
            try (SqlSession sqlSession = sqlSessionFactory.openSession()) {  
                // ... 使用 sqlSession 调用 Mapper 接口的方法 ...  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}

5. JDK 动态代理

在 MyBatis 的内部实现中,当通过 sqlSession.getMapper(UserMapper.class) 获取 Mapper 接口的实例时,MyBatis 会使用 JDK 动态代理为 UserMapper 接口生成一个代理对象。但是,这部分代码是 MyBatis 框架内部实现的,我们不需要直接编写。

6. 方法调用与 SQL 执行

通过 sqlSession.getMapper(UserMapper.class) 获得的代理对象,我们可以像调用普通 Java 方法一样调用 Mapper 接口中的方法,MyBatis 会根据 XML 映射文件中的配置执行相应的 SQL 语句:

java 复制代码
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {  
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);  
    User user = userMapper.selectUserById(1); // 执行 SQL 查询

10. Mybatis的工作原理(重要)

MyBatis 的工作原理可以概括为以下几个重要步骤:

  1. mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件(或者Java文件配置)来构建SqlSessionFactory(SqlSessionFactory是线程安全的)
  2. SqlSessionFactory实例通过openSession方法开启一个SqlSession
  3. 通过SqlSession实例的getMapper方法获得指定的Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession

11. Mybatis实现一对一、一对多有几种方式

  1. 一对一
    1. 联合查询:联合查询是几个表联合查询,只查询一次,通过在 resultMap 里面配置 association 节点配置一对一的类就可以完成
    2. 嵌套查询:先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是
    3. 通过 association 配置,但另外一个表的查询通过 select 属性配置
  2. 一对多
    1. 联合查询:联合查询是几个表联合查询,只查询一次,通过在 resultMap 里面配置 collection 节点配置一对一的类就可以完成
    2. 嵌套查询:先查一个表,根据这个表里面的结果的外键id,去再另外一个表里面查询数据,也是
    3. 通过 collection 配置,但另外一个表的查询通过 select 属性配置

12. Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

MyBatis支持延迟加载

延迟加载(Lazy Loading)是一种加载数据的策略,它只在真正需要数据时才进行加载,从而有助于提高系统性能和减少资源消耗。在MyBatis中,延迟加载的实现原理如下:

  1. 配置延迟加载 :在MyBatis的配置文件或映射文件中,需要设置lazyLoadingEnabled=true来开启延迟加载功能。
  2. 生成代理对象:当主对象(如一个实体对象)被查询时,MyBatis会生成一个代理对象。这个代理对象包含了对关联对象的引用,但并不会立即加载关联对象的数据。
  3. 触发时机:当应用程序需要访问代理对象中的关联属性时,延迟加载机制会被触发。此时,MyBatis会创建一个新的SQL语句来查询关联对象的数据。
  4. 填充数据:查询完成后,MyBatis会将查询到的数据填充到代理对象中,使得关联属性变得可用。

MyBatis的延迟加载主要有两种类型:

  • 全局延迟加载(全局懒加载):在MyBatis的配置文件中配置开启全局延迟加载。这样,对于所有的关联关系,都会按照配置进行延迟加载。
  • 按需延迟加载(按需懒加载) :在映射文件中使用fetchType属性设置按需延迟加载。这样,只有在需要的时候才会进行延迟加载。

通过配置全局延迟加载或按需延迟加载,可以根据实际业务需求灵活地使用延迟加载功能,从而提高系统性能。

13. 说说Mybatis的缓存机制

Mybatis 有两级缓存,一级缓存是 SqlSession 级别的,默认开启,无法关闭;二级缓
存是 Mapper 级别的,二级缓存默认是没有开启的,但是手动开启

  1. 一级缓存:基础 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,Session 中的所有 Cache 就将清空

  2. 二级缓存其存储作用域为 Mapper(Namespace),使用二级缓存属性类需要实现Serializable 序列化接口

  3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存 Namespaces)的进行了 C(增加)/U(更新)/D(删除)操作后,默认该作用域下所有 select 中的缓存将被 clear.需要在 setting 全局参数中配置开启二级缓存,如下 conf.xml 配置:


当我们的配置文件配置了 cacheEnabled=true 时,就会开启二级缓存,二级缓存是
mapper 级别的,如果你配置了二级缓存,那么查询数据的顺序应该为:二级缓存→一级缓
存→数据库。

相关推荐
魔道不误砍柴功33 分钟前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_23433 分钟前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨36 分钟前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟2 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity3 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天3 小时前
java的threadlocal为何内存泄漏
java
caridle3 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^3 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋33 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx
秋の花4 小时前
【JAVA基础】Java集合基础
java·开发语言·windows