Mybatis的二级缓存 (ehcache方式)

news2025/1/11 17:58:28

目录

  • 前置
  • pom: jar
  • 配置文件: ehcache.xml
  • 配置指定方式
  • 恢复 .index 文件 (ApplicationClosedEventListener.java)
  • 效果图


前置

会演示二级缓存生效/失效的场景
项目地址: https://gitee.com/xmaxm/test-code/blob/master/chaim-cache/chaim-mybatis-cache/chaim-mybatis-cache-two/README.md

前置配置:

本篇文章是基于上篇文章进行: https://blog.csdn.net/qq_38637558/article/details/127924334

注意点

官网地址:
https://www.ehcache.org/documentation
http://mybatis.org/ehcache-cache/index.html
如清除策略、可读或可读写等,不能应用于自定义缓存

强调:

通过.index文件进行数据的恢复. 可参考 ApplicationClosedEventListener.java
磁盘已经写入了数据, 重启项目的时候, 发现还是从数据库查, 第一次命中率还是0, 需要执行以下方法.

源码部分

感觉要是把源码过一遍, 得从新起一篇文章才行, 后面有需要在写, 偷个懒吧, 哈哈哈哈哈!

源码入口: org.apache.ibatis.mapping.CacheBuilder#build
关键类: org.apache.ibatis.cache.Cache
实现类: org.mybatis.caches.ehcache.EhcacheCache
org.mybatis.caches.ehcache.AbstractEhcacheCache
淘汰策略: 没得

相关缓存文章

Mybatis的一级缓存
Mybatis的二级缓存 (默认方式)
Mybatis的二级缓存 (Redis方式)
Mybatis的二级缓存 (ehcache方式)


pom: jar

没有使用过这个cache框架, 不过整体实现代码也没有几个类, 可以读一下

<!-- 自定义二级缓存存储: ehcache方式 -->
<dependency>
	<groupId>org.mybatis.caches</groupId>
	<artifactId>mybatis-ehcache</artifactId>
	<version>1.2.2</version>
	<!-- 不传递依赖 -->
	<optional>true</optional>
</dependency>

配置文件: ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">

    <!-- 磁盘缓存位置
    path属性可以配置的目录有:
    user.home(用户的家目录)
    user.dir(用户当前的工作目录)
    java.io.tmpdir(默认的临时目录)
    ehcache.disk.store.dir(ehcache的配置目录)
    绝对路径(如:d:\\ehcache)
    -->
    <diskStore path="F:\upload\EhCache"/>

    <!--
        name:缓存名称。
        maxElementsInMemory:缓存最大个数。
        eternal:对象是否永久有效,一但设置了,timeout将不起作用。
        timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
        timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
        overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
        diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
        maxElementsOnDisk:硬盘最大缓存个数。
        diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
        diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
        memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
        clearOnFlush:内存数量最大时是否清除。
    -->


    <!-- 默认缓存 -->
    <defaultCache
            eternal="true"
            maxElementsInMemory="1000"
            overflowToDisk="false"
            diskPersistent="true"
            timeToIdleSeconds="0"
            timeToLiveSeconds="0"
            memoryStoreEvictionPolicy="LRU"/>

    <!-- 自定义缓存 -->
    <cache
            name="MyCache"
            eternal="true"
            maxElementsInMemory="1000"
            overflowToDisk="false"
            diskPersistent="true"
            timeToIdleSeconds="0"
            timeToLiveSeconds="0"
            memoryStoreEvictionPolicy="LRU">

        <!-- 初始化缓存,以及自动设置. 重启项目取到缓存数据 -->
        <!-- 通过ApplicationClosedEventListener.java配置文件生效, 该配置并未生效 -->
        <!--<BootstrapCacheLoaderFactory-->
        <!--        class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"-->
        <!--        properties="bootstrapAsynchronously=true" />-->
    </cache>


</ehcache>

配置指定方式

配置:
@CacheNamespace(implementation = EhcacheCache.class)
或 <cache type=“org.mybatis.caches.redis.EhcacheCache”/>

备注:
@CacheNamespace(implementation = EhcacheCache.class)
对应的xml文件:
<cache-ref namespace=“com.chaim.mybatis.cache.two.mappers.SysUserMapper”/>
---------------------------------------
@CacheNamespaceRef(value = SysUserMapper.class)
对应的xml文件:
<cache type=“org.mybatis.caches.redis.EhcacheCache”/>

@CacheNamespace(implementation = EhcacheCache.class)
public interface SysUserMapper extends BaseMapper<SysUser> {
}
<cache type="org.mybatis.caches.redis.EhcacheCache"/>

恢复 .index 文件 (ApplicationClosedEventListener.java)

package com.chaim.mybatis.cache.two.config;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 监听项目停止运行
 * 用于处理 mybatis-ehcache 停止时调用 shutdown() 方法, 生成用于恢复的 .index 文件
 * 当 CacheManager 存在的时候该类才会进行 IOC
 *
 * @author Chaim
 * @date 2022/9/10 2:14
 */
@ConditionalOnClass(name = {"net.sf.ehcache.CacheManager"})
@Component
@Slf4j
public class ApplicationClosedEventListener implements ApplicationListener<ContextClosedEvent> {

    /**
     * 这一串最终执行的代码:
     * CacheManager cacheManager = CacheManager.getInstance();
     * cacheManager.shutdown();
     * 考虑到可能自定义二级缓存不采用此方式, 那么pom就不会导入对应的jar, 避免代码报错使用反射方式
     *
     * @param contextClosedEvent
     */
    @SneakyThrows
    @Override
    public void onApplicationEvent(ContextClosedEvent contextClosedEvent) {
        // 通过反射避免引入包 CacheManager 不存在编译报错
        Class<?> aClass = Class.forName("net.sf.ehcache.CacheManager");

        // 静态方法
        Method getInstance = aClass.getMethod("getInstance");
        Object invoke = getInstance.invoke(aClass);

        Method shutdown = aClass.getMethod("shutdown");
        shutdown.invoke(invoke);
        log.info("程序已停止");
    }
}

效果图

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/22640.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于PHP+MySQL汽车票订票系统的设计与实现(含论文)

从前,对汽车站的管理和规范问题一直是困扰政府的一个大难题,如何让人们方便快捷的买到自己想去的城市的票一直是一个问题。 但是现在,随着时代的飞速发展,交通越来越发达,人们可以更加方便的去各个城市,回家也好,旅游也好,当然,科学技术也在提高,出现了网上购票的新的购票方式,…

redux 和 react-redux

Redux 一、redux 工作流 二、创建 redux npm install redux src/redux/languageReducer.ts 数据处理逻辑 // 数据类型 export interface LanguageState {language: "en" | "zh"languageList: {name: string

Springboot 小巧简便的限流器使用 RateLimiter

前言 之前&#xff0c;写过一篇基于redis限流&#xff0c;能应用到分布式相关场景&#xff1a;&#xff08;Redis使用系列&#xff09; Springboot 使用redis实现接口Api限流 十_小目标青年的博客-CSDN博客 也在很久之前&#xff0c;写过一个使用也非常便捷的&#xff0c;整合…

Google Earth 成长历程的15个小故事

利用 Google Earth&#xff0c;可以像宇航员一样从太空中看到我们的星球&#xff0c;只需点击或轻触几秒钟就可以在地球上的任何地方旅行。如今的 Google Earth 仍然是世界上最大的可公开获取的地理图像存储库。它将航空摄影、卫星图像、3D 地形、地理数据和街景组合成一幅可以…

web前端面试-10大经典题(HTML基础)

HTML基础 1. HTML 文件中的 DOCTYPE 是什么作用&#xff1f; HTML超文本标记语言: 是一个标记语言, 就有对应的语法标准 DOCTYPE 即 Document Type&#xff0c;网页文件的文档类型标准。 主要作用是告诉浏览器的解析器要使用哪种 HTML****规范 或 XHTML****规范 来解析页面…

项目部署与拉取Github/Gitlab/Gitee的合理步骤以及会遇到的问题

踩了很多坑&#xff0c;总结一下。首先有两种需求&#xff0c;第一种是本地的项目部署到Github上&#xff0c;第二种是将团队的项目拉到本地。 &#xff08;初始&#xff09;本地 -> GitHub 因为本地到Github有可能是第一次去推送代码&#xff0c;也有可能是你更改了拉下来…

12V铅酸电池充放电保护板

现有铅酸电池特性&#xff1a; 重量&#xff1a;3斤电压范围&#xff1a;13.5~13.8V 14.4V~14.7V最大输出电流&#xff1a;2.16A 选用芯片&#xff1a;CN3768&#xff0c;4A&#xff0c;12V铅酸电池充放电管理集成电路 概述 CN3768是PWM降压模式12V铅酸电池充电管理集成…

关于python函数,你该了解这些

目录 1.创建一个函数 举例 2.调用函数 形参 实参 位置参数 关键字参数 可变长参数 其他 变量的作用域 全局变量 局部变量 3.匿名函数 1.创建一个函数 语法格式 def functionname([parameterlist]):[functionbody] functionname:函数名称&#xff0c;在调用函数时…

[附源码]java毕业设计闲置物品线上交易系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

web课程设计使用html+css+javascript+jquery技术制作个人介绍6页

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

追踪这9大关键DTC指标,将帮助你建立势头并释放增长

由于新冠疫情与检疫要求迫使品牌在分销产品的方式上进行创新&#xff0c;许多品牌转向了DTC模式。现在&#xff0c;DTC模式的吸引力越来越强&#xff0c;竞争也越来越激烈。在激烈的竞争中&#xff0c;犯一点小错误都可能贻害无穷。企业必须站在市场最前端&#xff0c;并专注自…

ts泛型,映射,条件类型和类型提取infer和一些常用工具库的说明

Typescript当中的T,K,V到底是个啥 有时候,我们看到下面的代码,当然,这里是简单例子来说 function identity <T> (value:T) : T {return value; }其实泛型就是使用字母来代替将要接收的类型,这里的"T"是代表类型的缩写,表示对将要接收类型的一个占位符,占位符…

【k8s】4、资源管理命令-陈述式

文章目录一、资源管理介绍1、资源管理概念1、资源管理方式二、 陈述式对象管理1、基本概念2、基础命令使用3、基本信息查看&#xff08;kubectl get&#xff09;4、增删等操作5、登录pod中的容器6、扩容缩容pod控制器的pod7、标签操作&#xff08;labels&#xff09;8、简单案例…

5G无线技术基础自学系列 | 5G信道结构

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 5G的信道包括逻辑信道、传输信道、物理…

jdk线程池ThreadPoolExecutor优雅停止原理解析(自己动手实现线程池)(二)

ThreadPoolExecutor优雅停止源码分析(自己动手实现线程池v2版本) ThreadPoolExecutor为了实现优雅停止功能&#xff0c;为线程池设置了一个状态属性&#xff0c;其共有5种情况。 在第一篇博客中曾介绍过&#xff0c;AtomicInteger类型的变量ctl同时维护了两个业务属性当前活跃…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.8 变更缓存供应商 memcached

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.8 变更缓存供应商 memcached5.8.1 memcached 缓存…

如何在 Navicat 16 中仅备份数据库结构 | 数据传输

尽管有少数据库管理员&#xff08;DBA&#xff09;不相信执行定期数据库备份是有用的&#xff0c;但对于如何最好地执行此操作有很多意见。无论你采用哪种方法&#xff0c;都有很多充分的理由保留数据库模式的副本。当发生数据丢失时&#xff0c;你可以从模式中还原数据库结构&…

[附源码]SSM计算机毕业设计二手车交易系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Java中的final和常量以及枚举

Java中的final和常量以及枚举final的作用常量常量概述和基本作用常量做信息标志和分类枚举枚举的概念定义枚举类的格式枚举的特征final的作用 1.final关键字是最终的意思&#xff0c;可以修饰&#xff08;类、方法、变量&#xff09; 2.修饰类&#xff1a;表明该类是最终类&am…

数据结构之:链表

链表初体验之单链表 线性表 线性表"线性存储结构" —— 一根线能串起来的数组 存储到物理空间之中 数据需要有相同的数据类型 元素之间的关系 需要是“一对一” 两种存储方式“顺序” 和“链式”链表介绍 分为有头节点的链表和没有头节点的链表。 插入的时候&#xf…