Mushroom Notes Mushroom Notes
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • 总览
  • 常用mate
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 数据库

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
📚技术
  • 方案专题
  • 算法专题
  • BUG专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档

kinoko

一位兴趣使然的热心码农
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • 总览
  • 常用mate
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 数据库

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
📚技术
  • 方案专题
  • 算法专题
  • BUG专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档
  • Spring

  • SpringCloud

  • 数据库

    • Mybatis
      • mybatis-config.xml配置文件
        • 手动获取sqlSession对象
      • MyBatis三种开发方式
        • 接口代理的开发方式
        • 事务
        • 获取新增记录的主键值
        • 多条件查询, 参数接收
        • 注解开发方式
      • 动态SQL
        • if标签格式
        • where标签
        • choose标签
        • set标签
        • foreach标签
        • sql标签与include标签
      • MyBatis的参数处理
      • resultMap输出映射
        • 表关系
        • 级联查询
      • MyBatis缓存
        • 一级缓存
        • 二级缓存
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

  • 框架
  • 数据库
kinoko
2023-12-17
目录

Mybatis


image.png
MyBatis简介

MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发
MyBatis 本是 Apache 的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github
官网:https://mybatis.org/mybatis-3/zh/index.html (opens new window)
MyBatis 免除了几乎所有的 JDBC 代码,以及设置参数和获取结果集的工作

# mybatis-config.xml配置文件


image.png

<?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>
  	<settings>
        <!--在控制台显示SQL语句及查询结果-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
      	<!--映射适配驼峰命名规则-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
  	<!--定义实体类别名-->
    <typeAliases>
        <package name="包名"/>
    </typeAliases>
    <environments default="default">
      	<!--环境变量-->
        <environment id="default">
          	<!--事务管理器-->
            <transactionManager type="JDBC"/>
          	<!--数据源-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
		
  	<!--加载其它映射文件-->
    <mappers>
   		<!--扫描resource文件夹下的指定映射文件-->
        <mapper resource="xml文件名"/>
        <!--package标签: 扫描包里面的所有映射文件-->
        <package name="包名"/>
    </mappers>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

配置映射文件包扫描注意事项:
前提:(以编译后的target文件夹为准)

  1. xml映射文件要与接口名一致
  2. xml映射文件要与接口处于同级目录

mapper映射文件

<?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">

<!--namespace配置接口-->
<!--resultType返回值类型如果是集合,
        则只需要写集合存放的泛型即可,自定义类要注意加上包名-->
<mapper namespace="包名.接口名">
    <select id="方法名" resultType="方法返回值类型">
        SQL语句
    </select>
</mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13

# 手动获取sqlSession对象

// 加载核心配置文件,获取SqlSessionFactory对象(获取resource目录下的资源)
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");

// 获取SqlSession对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();

// 执行SQL语句
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.findAllUsers();
users.forEach(System.out::println);

// 释放资源
sqlSession.close();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# MyBatis三种开发方式


  1. 接口代理的开发方式(重点)
  2. 传统DAO实现类的开发方式(目前淘汰)
  3. 使用注解的开发方式(重点)

一般来说,简单sql需求可以用注解方式,复杂sql使用xml配置的方式

# 接口代理的开发方式


开发步骤

  1. 创建接口添加SQL业务方法
  2. 配置接口映射文件接口名.xml
  3. 使用SqlSession对象执行Mapper方法

创建接口添加SQL业务方法

public interface UserMapper {
    List<User> findAllUsers();
    User selectOne(int id);
}
1
2
3
4

配置接口映射文件UserMapper.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.itheima.mapper.UserMapper">
    <select id="findAllUsers" resultType="com.itheima.pojo.User">
        SELECT * FROM user;
    </select>
    <select id="selectOne" resultType="com.itheima.pojo.User">
        SELECT * FROM user WHERE id=##{id};
    </select>
</mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13

注意:

符号 说明
##{变量名} 先使用?占位, 后续将具体值赋值给?
${变量名} 字符串拼接。会存在SQL注入问题
< 相当于<
> 相当于>

使用SqlSession对象执行Mapper方法

// 加载核心配置文件,获取SqlSessionFactory对象
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
// 获取SqlSession对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行SQL语句
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.findAllUsers();
users.forEach(System.out::println);
// 释放资源
sqlSession.close();
1
2
3
4
5
6
7
8
9
10
11

**注意:**MyBatis设计使用增删改操作时,若没有提交事务则会自动回滚事务,所以每次我们执行增删改语句后需要手动提交事务。

# 事务

相关API

方法 说明
sqlSession.commit() 手动提交事务
factory.openSession(true); 自动提交事务

说明
如果SQL语句每条都是独立的,使用自动提交
如果是多条SQL语句组成一个功能,手动提交

# 获取新增记录的主键值

通过属性useGeneratedKeys得到新增记录的主键值

属性 说明
useGeneratedKeys true,使用mysql生成的主键
keyProperty 实体类中对应的属性

示例

<insert id="add" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user VALUES(null ,##{username},##{birthday},##{sex},##{address});
</insert>
1
2
3
@Test
public void test3() throws IOException {
	SqlSession session = SqlUtil.getSession();
	UserMapper mapper = session.getMapper(UserMapper.class);
	User user = new User("张晓峰", Date.valueOf("2001-10-19"), "女", "福建");
	mapper.add(user);
	System.out.println(user);
	session.close();
}
1
2
3
4
5
6
7
8
9

# 多条件查询, 参数接收


  1. 散装参数: 如果方法中有多个参数,需要使用@Param("SQL参数占位符名称")
  2. 对象参数: 对象的属性名称要和参数占位符名称一致
  3. Map集合参数: Map的键要和占位符名称一致

示例

public interface UserMapper {
    // 多条件查询
    List<User> selectByCondition(@Param("username") String username,
                                 @Param("sex") String sex);
    List<User> selectByCondition(User user);
    
    // map集合键为参数名,值为参数值,如:{"id"=id,"username"=username,"sex"=sex}
    // 键名要与mapper配置中的占位符名对应
    List<User> selectByCondition(Map map);
}
1
2
3
4
5
6
7
8
9
10
<!-- 或者修改SQL语句中的占位,如##{param1}{prarm2}或者{arg1}{arg2} -->
<select id="selectByCondition" resultType="com.itheima.pojo.User">
    SELECT * FROM user WHERE username LIKE ##{username} AND sex=##{sex};
</select>
1
2
3
4

# 注解开发方式


注解

注解名 说明
@Select 查询
@Insert 添加
@Update 修改
@Delete 删除
@Results 封装映射关系的父注解,相当于<resultMap>

value属性:定义了 Result 数组
@Result 封装映射关系的子注解,相当于<result>

id属性 :id=true相当于id标签,false则是result标签
column 属性:查询出的表中字段名称
property 属性:实体对象中的属性名称
one 属性:一对一查询固定属性
many 属性:一对多查询固定属性
@One 一对一查询,相当于<association>

select属性:调用下个查询的接口方法
@Many 一对多查询,相当于<collection>

select属性:调用下个查询的接口方法
@Options 设置标签属性

仅适用于有主键自增的数据库(Oracle就不适用)
useGenerateKeys = true:获取新增语句后自增的键
keyProperty:主键对应的实体类属性
keyColumn:主键对应的表字段
@SelectKey 获取新增主键

适用于所有的数据库
statement = "select last_insert_id()":查询最后一条插入语句的id
before = false:在插入语句前还是后执行true前,false后
keyProperty:主键对应的实体类属性
keyColumn:主键对应的表字段
resultType = 类型.class:主键类型

**注意:**注解只支持级联查询方式的多表查询

一对一示例

// 一对一: 通过用户ID查询用户基本信息
@Select("SELECT * FROM user WHERE id=##{id};")
@Results(value = {
        @Result(id = true, column = "id", property = "id"), 
        @Result(property = "userInfo", column = "id",
            one = @One(select = "findUserInfo")
        )
})
User findUserById(int uid);

// 一对一: 通过用户ID查询用户扩展信息
@Select("SELECT * FROM user_info WHERE id=##{uid};")
UserInfo findUserInfo(int uid);
1
2
3
4
5
6
7
8
9
10
11
12
13

一对多示例

@Select("SELECT * FROM user WHERE id=##{id};")
@Results(value = {
        @Result(id = true, column = "id", property = "id"), // 注解开发多表查询需要配置主键
        @Result(property = "userInfo", column = "id",
            one = @One(select = "findUserInfo")
        ),
        @Result(property = "orders", column = "id",
            many = @Many(select = "findOrders")
        )
})
User findUserById(int uid);

// 一对多: 通过用户ID查询用户的所有订单
@Select("SELECT * FROM `order` WHERE user_id=##{uid};")
List<Order> findOrders(int uid);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 动态SQL


**动态SQL指的是:**在程序运行时,根据不同的情况,拼接最终执行的sql语句。

# if标签格式

<if test="条件">
  SQL片段
</if>
1
2
3

**if标签作用:**当条件为true则拼接SQL语句

# where标签

作用:

  1. 相当于where关键字,自动补全where这个关键字
  2. 去掉多余的and、or、where关键字

示例

<select id="selectByCondition" resultType="com.itheima.pojo.User">
    SELECT * FROM user 
    <where>
        <if test="username!=null and username!=''">
            username LIKE ##{username}
        </if>
        <if test="sex!=null and sex!=''">
             AND sex=##{sex};
        </if>
    </where>
</select>
1
2
3
4
5
6
7
8
9
10
11

**注意:**if标签内的条件表达式不能大写,也不需要##{}

# choose标签

**作用:**只执行其中一个语句

示例

<select id="findFuzzyNameOrStatus" resultType="brand">
        SELECT * FROM tb_brand
        <where>
            <choose>  
            <when test="status!=null">
                `status`= ##{status}
            </when>
            <when test="brandName!=null and brandName!=''">
                AND brand_name LIKE "%"##{brandName}"%"
            </when>
            <when test="companyName!=null and companyName!=''">
                AND company_name LIKE "%"##{companyName}"%"
            </when>
            <otherwise>
                
            </otherwise>
            </choose>
        </where>
    </select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# set标签

作用:

  1. 用在update语句中,相当于set关键字
  2. 去掉SQL代码片段中后面多余的逗号

示例

<update id="update">
    UPDATE user
    <set>
        <if test="username!=null and username!=''">
            username=##{username},
        </if>
        <if test="birthday!=null"> // Date类型无需和空字符串比较
            birthday=##{birthday},
        </if>
        <if test="sex!=null and sex!=''">
            sex=##{sex},
        </if>
        <if test="address!=null and address!=''">
            address=##{address}
        </if>
    </set>
    WHERE id=##{id};
</update>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# foreach标签

作用:遍历数组或集合

foreach标签的属性 作用
collection 参数名
item 设置变量名,代表每个遍历的元素
separator 遍历一个元素添加的内容
##{变量名} 先使用?占位, 后面给?赋值
open 在遍历前添加一次字符
close 在遍历后添加一次字符

示例

public interface UserMapper {
    // 批量删除
    void deleteByIds(@Param("ids") int[] ids);
}
1
2
3
4
<delete id="deleteByIds">
    DELETE FROM user WHERE id IN
    <foreach collection="ids" item="ele" open="(" close=");" separator=",">
        ##{ele}
    </foreach>
</delete>
1
2
3
4
5
6

# sql标签与include标签


作用

  1. sql标签:定义一段SQL语句,起个名字可以重用。
  2. include标签:引入上面定义的SQL代码段。
<!--抽取重复的SQL并取个名字-->
<sql id="commont">
		INSERT INTO user (username,birthday,sex,address) VALUES
</sql>
<insert id="addUsers" parameterType="list">
    <!--引入上面的的SQL-->
    <include refid="commont"/>
    <foreach collection="list" close=";" separator="," item="user">
      (##{user.username},##{user.birthday},##{user.sex},##{user.address})
    </foreach>
</insert>
1
2
3
4
5
6
7
8
9
10
11
<sql id="sqlCondition">
  <where>
    <if test="status!=null">
      STATUS=##{status}
    </if>
    <if test="brandName!=null and brandName!=''">
      AND brand_name LIKE "%"##{brandName}"%"
    </if>
    <if test="companyName!=null and companyName!=''">
      AND company_name LIKE "%"##{companyName}"%"
    </if>
  </where>
</sql>

<select id="findBySBC" resultType="cn.kk.pojo.Brand">
  SELECT * FROM tb_brand
  <include refid="sqlCondition"></include>
    </select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# MyBatis的参数处理


  • 单个参数:

**基本数据类型:**mybatis底层没有处理,直接使用 ##{参数名}
**POJO类型:**mybatis底层没有处理,直接使用 ##{成员属性名},属性名 和 参数占位符名称 一致
**Map集合:**mybatis底层没有处理,直接使用##{键名},键名 和 参数占位符名称 一致
**Collection:**封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",collection集合);
map.put("collection",collection集合);
**List:**封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",list集合);
map.put("collection",list集合);
map.put("list",list集合);
**Array:**封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",数组);
map.put("array",数组);
**其他类型:**直接使用

  • **多个参数:**封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
    map.put("arg0",参数值1)
    map.put("param1",参数值1)
    map.put("param2",参数值2)
    map.put("agr1",参数值2)
    ---------------@Param("username") @Param("sex")
    map.put("username",参数值1)
    map.put("param1",参数值1)
    map.put("param2",参数值2)
    map.put("sex",参数值2)

最后就是通过foreach标签遍历这个map集合来获取值

org.apache.ibatis.reflection包下的ParamNameResolver类

// Object[] args:存放接收到的参数
public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();
  
  	// 处理无参的情况
    if (args == null || paramCount == 0) {
      return null;
    }
    
    // 处理一个参数并且没有注解的情况
    else if (!hasParamAnnotation && paramCount == 1) {
      Object value = args[names.firstKey()];
        
      // 判断这个参数是否是集合或者数组类型,是则转成Map,否则直接返回
      return wrapToMapIfCollection(value, useActualParamName ? names.get(0) : null);
    } 
    
    // 如果有注解
    else {
        
       // 定义一个Map集合来装自定义传参
      final Map<String, Object> param = new ParamMap<>();
      int i = 0;
        
       // 注解内定义的变量名会存入names这么一个Map集合 例:@Param("coll")的coll
      for (Map.Entry<Integer, String> entry : names.entrySet()) {
          
        // 取出注解属性,存入param集合中 {"coll",参数值}
        param.put(entry.getValue(), args[entry.getKey()]);
        // add generic param names (param1, param2, ...)
        final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
        // ensure not to overwrite parameter named with @Param
          
        // {"param(i+1)",参数值} 例:{"param1",参数值}
        if (!names.containsValue(genericParamName)) {
          param.put(genericParamName, args[entry.getKey()]);
        }
        i++;
      }
      return param;
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# resultMap输出映射


使用场景

MyBatis默认使用resultType属性把查询的结果自动封装成Java类对象,但前提是需要查询结果字段名与类成员属性名对应。当查询结果的字段与需要封装的pojo类成员属性名无法对应时,可以使用resultMap标签手动建立查询的列与对象属性的对应关系。

# 表关系


MySQL的多表关系在Java中的体现形式

  • **一对一:**在A表的pojo类属性中存放B表的pojo类对象
  • **一对多:**在A表的pojo类属性中存放B表的pojo类对象的集合
  • **多对多:**在A表的pojo类属性中存放B表的pojo类对象的集合,在B表的pojo类属性中存放A表的pojo类对象的集合;**注意:**java中的多对多是不需要中间表的,拆分为两个一对多就可以了。

resultMap标签

属性 **说明 **
id标签 唯一标识,对主键字段进行映射
result标签 要封装的类型,对普通字段进行映射
association标签 表一对一的映射
collection 表一对多的映射
type属性 映射的pojo类名
column属性 表字段名
property属性 映射字段名
autoMapping属性 启用自动映射名字对应的属性,但不能省略主键

示例

<!--user表-->
<resultMap id="UserMap" type="User" autoMapping="true">
    <id column="id" property="id"/>
    <!--association: 一对一的映射-->
    <association property="userInfo" resultMap="UserInfoMap"/>
  	<!--collection: 一对多的映射-->
  	<collection property="orders" resultMap="OrderMap"/>
</resultMap>

<!--user_info表-->
<resultMap id="UserInfoMap" type="UserInfo" autoMapping="true"/>

<!--order表-->
<resultMap id="OrderMap" type="Order">
    <id column="oid" property="oid"/>
    <result column="user_id" property="userId"/>
    <result column="number" property="number"/>
    <result column="create_time" property="createTime"/>
    <result column="note" property="note"/>
</resultMap>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

**补充:**在核心配置文件中使用settings设置mapUnderscoreToCamelCase为true可以映射下划线为驼峰命名法。例:<setting name="mapUnderscoreToCamelCase" value="true"/>

**扩展:**可以通过collection灵活配置需要映射的字段

<!--role表-->
<!--ofType:映射的pojo类-->
<collection property="users" ofType="User">
	<id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="birthday" property="birthday"/>
    <result column="sex" property="sex"/>
    <result column="address" property="address"/>
</collection>
1
2
3
4
5
6
7
8
9

# 级联查询


级联查询是支持延迟加载的:当一张表中的数据没有被访问时,不会执行sql语句
延迟加载需要在settings中配置:

<**setting **name="lazyLoadingEnabled" value="true"/>

<**setting **name="aggressiveLazyLoading" value="false"/>

association:一对一的级联查询

参数

association标签的属性 说明
property 指定另一方在当前实体类中属性名
column 当前查询结果的字段值,以及传给下一个SQL需要的参数
select 下一个执行的查询的接口方法名字

示例

<resultMap id="UserMap" type="User" autoMapping="true">
    <id column="id" property="id"/>
    <!--association: 一对一的映射-->
    <association property="userInfo" select="findUserInfoById" column="id"/>
</resultMap>

<select id="findUserById" resultMap="UserMap">
    SELECT * FROM USER WHERE id=##{uid};
</select>

<select id="findUserInfoById" resultType="UserInfo">
    SELECT * FROM user_info WHERE id=##{uid};
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13

**注意:**association级联查询中的下一个查询需要的参数必须只有一个

collection:一对多的级联查询

参数

collection标签的属性 说明
property 指定另一方在当前实体类中属性名
column 当前查询结果的字段值,以及传给下一个SQL需要的参数
select 下一个执行的查询的接口方法名字

示例

<resultMap id="UserMap" type="User" autoMapping="true">
    <id column="id" property="id"/>
    <collection property="orders" select="findOrders" column="id"/>
</resultMap>
<!--通过用户ID查询用户的基本信息-->
<select id="findUserById" resultMap="UserMap">
    SELECT * FROM USER WHERE id=##{uid};
</select>

<!--通过用户ID查询用户的所有订单-->
<select id="findOrders" resultType="Order">
    SELECT * FROM `order` WHERE user_id=##{uid};
</select>
1
2
3
4
5
6
7
8
9
10
11
12
13

**补充:**可以在mybatis核心配置文件的settings中添加<**setting **name="logImpl" value="STDOUT_LOGGING"/>显示执行的SQL语句

# MyBatis缓存


简介

MyBatis框架提供了缓存策略,通过缓存策略可以减少查询数据库的次数,提升系统性能。在MyBatis框架中缓存分为一级缓存和二级缓存。
image.png

# 一级缓存

一级缓存是sqlSession范围的缓存,只能在同一个sqlSession内部有效。它本身已经存在,一级缓存不需要手动处理,可以直接使用。

第一次查询数据时,会将查询的数据放入一级缓存中。后面的相同查询直接从缓存中获取。
**注意:**一级缓存是 SqlSession 范围缓存。当调用 SqlSession 的修改、添加、删除、提交、关闭等方法时,一级缓存会被清空。

手动清除缓存:sqlSession.clearCache();

# 二级缓存

二级缓存是mapper映射级别缓存,作用范围跨越SqlSession,即可以在多个SqlSession之间共享二级缓存数据。

使用二级缓存的注意事项:

  1. 实体类需要实现Serializable接口
    1. 因为二级缓存作用范围跨越SqlSession,所以当缓存不够用时,会序列化到文件中
  2. 在 mybatis-config.xml 配置开启二级缓存
    1. 在settings标签中添加<setting name="cacheEnabled" value="true">
  3. 在 XXXMapper.xml 开启二级缓存使用
    1. 在映射文件中添加<cache/>标签,用于声明该映射文件中的所有查询结果都会放到二级缓存中
#mybatis#mb
上次更新: 2023/12/29 11:32:56
Kafka
Mybatis Plus

← Kafka Mybatis Plus→

最近更新
01
JVM 底层
09-13
02
JVM 理论
09-13
03
JVM 应用
09-13
更多文章>
Theme by Vdoing | Copyright © 2022-2024 kinoko | MIT License | 粤ICP备2024165634号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式