当前位置: 首页 > news >正文

【MyBatis笔记12】MyBatis中二级缓存相关配置内容

这篇文章,主要介绍MyBatis中二级缓存相关配置信息。

目录

一、MyBatis二级缓存

1.1、cache标签相关属性

(1)eviction属性

(2)size属性

(3)flushInternal属性

(4)readOnly属性

(5)type属性


一、MyBatis二级缓存

缓存的作用就是暂时将数据保存在计算机的内存里面,这样,下次查询的时候可以直接从内存里面获取数据,而不用再到数据库里面查询,从而提高了查询效率。

因为是将数据保存再内存里面的,所以不能保存太多数据,这样就需要对二级缓存做一些处理,例如:当缓存过多的时候,要怎么办,最多保存多少缓存数据,刷新缓存的时间等等配置,下面详细介绍一下。

1.1、cache标签相关属性

在XML映射文件中,使用【<cache/>】标签启用二级缓存,这个标签中有许多的属性可以用于设置二级缓存。

(1)eviction属性

eviction属性用于指定缓存回收策略,这里的回收策略就是指:当MyBatis二级缓存过多的时候,需要采用哪种方式将缓存删除一些。

eviction属性的可选值有如下几个:

  • LRU(Least Recently Used):最近最少使用,缓存过多时候,首先删除最久时间没有使用的缓存数据。
  • FIFO(First In First Out):先进先出,缓存过多时候,按照缓存保存的先后顺序删除,先保存的先删除。
  • SOFT(软引用):缓存过多时候,按照软引用规则删除数据。
  • WEAK(弱引用):缓存过多时候,按照弱引用规则删除数据。

二级缓存默认采用的是【LRU】回收策略。

<?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.mybatis.demo.mapper.UserMapper">
    <!-- 启用二级缓存 -->
    <cache eviction="LRU"/>
    <!-- 缓存查询 -->
    <select id="query" parameterType="com.mybatis.demo.domain.User" resultType="com.mybatis.demo.domain.User">
        select * from user
        <where>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="password != null">
                and password = #{password}
            </if>
            <if test="id != null">
                and id = #{id}
            </if>
        </where>
    </select>
</mapper>

(2)size属性

size属性,用于设置二级缓存最多能够存储多少个引用对象,也就是最多保存多少对象。当数据超过设置的大小之后,多余的数据不会保存到二级缓存里面。

<?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.mybatis.demo.mapper.UserMapper">
    <!-- 启用二级缓存 -->
    <cache eviction="LRU" size="1"/>
    <!-- 缓存查询 -->
    <select id="query" parameterType="com.mybatis.demo.domain.User" resultType="com.mybatis.demo.domain.User">
        select * from user
        <where>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="password != null">
                and password = #{password}
            </if>
            <if test="id != null">
                and id = #{id}
            </if>
        </where>
    </select>
</mapper>

(3)flushInternal属性

flushInternal属性,用于设置二级缓存的刷新时间间隔,单位是:【毫秒】。MyBatis默认情况是不会设缓存刷新时间间隔的,并且只有在执行对应的SQL查询语句之后,才会触发缓存刷新的时间间隔。

举个例子:设置缓存刷新时间间隔为3000毫秒,那么在调用对应的查询方法之后,过了3000毫秒之后就会刷新一次二级缓存。

<?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.mybatis.demo.mapper.UserMapper">
    <!-- 启用二级缓存 -->
    <cache eviction="LRU" size="1" flushInterval="1000"/>
    <!-- 缓存查询 -->
    <select id="query" parameterType="com.mybatis.demo.domain.User" resultType="com.mybatis.demo.domain.User">
        select * from user
        <where>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="password != null">
                and password = #{password}
            </if>
            <if test="id != null">
                and id = #{id}
            </if>
        </where>
    </select>
</mapper>

(4)readOnly属性

readOnly属性,用于标识缓存数据是否只读,取值是:true和false。

  • readOnly设置为true时候,那么从缓存中查询出来的数据是原数据,一般不能够进行修改操作,表示只读状态。
  • readOnly设置为false时候,那么从缓存中查询出来的数据是原数据的一个副本,可以对副本数据进行修改,不影响原数据。

下面通过一个案例来解释一下readOnly属性的使用。

  • 配置二级缓存只读。
<?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.mybatis.demo.mapper.UserMapper">
    <!-- 启用二级缓存 -->
    <cache eviction="LRU" size="5" flushInterval="10000" readOnly="true"/>
    <!-- 缓存查询 -->
    <select id="query" parameterType="com.mybatis.demo.domain.User" resultType="com.mybatis.demo.domain.User">
        select * from user
        <where>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="password != null">
                and password = #{password}
            </if>
            <if test="id != null">
                and id = #{id}
            </if>
        </where>
    </select>
</mapper>
  • 查询缓存数据。
// 执行操作
User user = new User();
user.setUsername("测试二级缓存");

// 第一次查询
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> query = userMapper.query(user);
System.out.println("第一次查询打印结果: ");
query.forEach(System.out::println);
// 关闭 SqlSession
sqlSession.close();
// 修改查询出来的缓存数据: 注意一定要在close() 之后修改,这样才能够修改二级缓存中的数据
for (User user1 : query) {
    // 修改缓存数据
    user1.setUsername("csdn");
}

// 第二次读取数据
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
List<User> query2 = userMapper2.query(user);
System.out.println("第一次查询打印结果: ");
query2.forEach(System.out::println);
// 关闭 SqlSession
sqlSession2.close();

运行上面代码,控制台查看输出结果,这个时候可以看到第一次查询出来的数据和第二次查询出来的数据结果不一样,第二次将缓存数据给修改了。

 当我们设置【flushInternal="false"】的时候,这个时候,在执行上面的代码,可以发现缓存中的数据没有被修改。

(5)type属性

type属性,用于设置自定义的缓存实现类,这个type属性几乎不怎么用,除非需要自定义缓存的逻辑(例如:项目中不使用MyBatis提供的二级缓存,而是需要使用第三方提供的缓存功能,如:Redis、Ehcache等第三方缓存)。如果没有设置type属性,那么会默认采用MyBatis框架中提供的缓存实现类【PerpetualCache】。

<?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.mybatis.demo.mapper.UserMapper">
    <!-- 启用二级缓存 -->
    <cache eviction="LRU" size="5" flushInterval="10000" readOnly="false"
        type="org.apache.ibatis.cache.impl.PerpetualCache"/>
    <!-- 缓存查询 -->
    <select id="query" parameterType="com.mybatis.demo.domain.User" resultType="com.mybatis.demo.domain.User">
        select * from user
        <where>
            <if test="username != null">
                and username = #{username}
            </if>
            <if test="password != null">
                and password = #{password}
            </if>
            <if test="id != null">
                and id = #{id}
            </if>
        </where>
    </select>
</mapper>

如果需要自定义的缓存逻辑,可以编写一个类,然后实现【Cache】接口,重写其中的方法即可。

package com.mybatis.demo.cache;

import org.apache.ibatis.cache.Cache;

/**
 * @author ZhuYouBin
 * @version 1.0.0
 * @Date: 2022/9/3 19:52
 * @Description
 */
public class CustomCache implements Cache {

    @Override
    public String getId() {
        return null;
    }

    @Override
    public void putObject(Object o, Object o1) {

    }

    @Override
    public Object getObject(Object o) {
        return null;
    }

    @Override
    public Object removeObject(Object o) {
        return null;
    }

    @Override
    public void clear() {

    }

    @Override
    public int getSize() {
        return 0;
    }
}

注意:MyBatis的二级缓存一般不会使用,而是使用自定义的第三方缓存,例如:EHCache。

以上,就是MyBatis二级缓存相关的配置信息。

综上,这篇文章结束了,主要介绍MyBatis中二级缓存相关配置信息。

相关文章:

  • EasyExcel 官网观看建议
  • 再苦再累也必须要弄懂的:ES6的ES Module
  • K210使用Mx-yolov3训练
  • Springboot中日志的简单使用
  • 0. SQL细节要点
  • 网络安全——Cobaltstrike
  • 架构师的 36 项修炼第07讲:高性能系统架构设计
  • 微信小程序开发03 自定义组件:怎么培养组件化思维?
  • 4.bs4 节点遍历
  • 基于ssm+vue+elementui的二手车交易管理系统
  • 计算机毕业设计springboot+vue基本微信小程序的水库巡检系统
  • 3.BeautifulSoup库
  • 8.cookie的获取
  • 商标注册需要什么材料
  • 什么是布隆过滤器
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 10个最佳ES6特性 ES7与ES8的特性
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • angular学习第一篇-----环境搭建
  • AWS实战 - 利用IAM对S3做访问控制
  • Git的一些常用操作
  • gulp 教程
  • JavaScript 一些 DOM 的知识点
  • Javascript编码规范
  • JavaScript创建对象的四种方式
  • js中forEach回调同异步问题
  • node-glob通配符
  • PHP的类修饰符与访问修饰符
  • Puppeteer:浏览器控制器
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • spring boot 整合mybatis 无法输出sql的问题
  • Vue2.0 实现互斥
  • 后端_ThinkPHP5
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 力扣(LeetCode)21
  • 使用putty远程连接linux
  • 移动端解决方案学习记录
  • 云大使推广中的常见热门问题
  • !!Dom4j 学习笔记
  • ![CDATA[ ]] 是什么东东
  • # Java NIO(一)FileChannel
  • #162 (Div. 2)
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • (70min)字节暑假实习二面(已挂)
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (二)c52学习之旅-简单了解单片机
  • (三) diretfbrc详解
  • (十) 初识 Docker file
  • (十二)springboot实战——SSE服务推送事件案例实现
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • .net core使用ef 6
  • .NET 命令行参数包含应用程序路径吗?