如何在Spring Boot中使用EhCache缓存

news2024/11/17 23:27:35

1、EhCache介绍

在查询数据的时候,数据大多来自于数据库,我们会基于SQL语句与数据库交互,数据库一般会基于本地磁盘IO将数据读取到内存,返回给Java服务端,我们再将数据响应给前端,做数据展示。

但是MySQL这种关系型数据库查询数据相对比较慢,因为有磁盘IO,或者是全盘扫描的风险,在针对一些热点数据时,会对MySQL造成比较大的压力,此时我们可以采用缓存的方式来解决。

而缓存又分为很多种,相对服务端角度来说,可以采用Redis和JVM这两种方式。

Redis不必多说,直接基于基于内存读写,并发读写的并发能力特别强,所以很多时间,在分布式或者微服务的项目中,为了保证数据一致性,我们会采用Redis来实现缓存。

但是在一些单体项目,我们可以采用JVM级别的缓存,比如直接采用框架自带的,例如Hibernate的缓存,MyBatis的缓存,或者是Guava提供的Cache,以及今儿要玩的EhCache。

还有一种情况可以采用JVM缓存,在分布式环境下,如果并发特别大,Redis也扛不住,这是我们可以将数据平均的分散在各个节点的JVM缓存中,并且设置一个较短的生存时间,这样就可以减缓Redis的压力,从而解决热点数据Redis扛不住的问题

同时EhCache也是Hibernate框架默认使用的缓存组件实现二级缓存。类似MyBatis,就直接用的HashMap。

2、引入EhCache

官网:http://www.ehcache.org

通过后缀就可以看出EhCache是开源的组件。

EhCache除了开源,还有可以几乎0成本和Spring整合的有点,毕竟现在Java项目大多都是基于Spring方式构建的,这也可以让我们在使用EhCache的时候更加方便。

这里还是单独的使用EhCache来感受一下,其实使用方式和HashMap的put和get的方式类似,不过EhCache提供了更加丰富的功能。

EhCache有2.x和3.x两个常用的大版本,两个版本API差异巨大,这里咱们以3.x为讲解的内容应用

官方入门文档:
Ehcache 3.10 Documentation

        <!-- ehcache依赖   -->
        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>3.8.1</version>
        </dependency>

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.6</version>
        </dependency>

3、复制配置文件

  • 复制xml文件

图片alt

<!-- Ehcache2.x的变化(取自https://github.com/springside/springside4/wiki/Ehcache) -->
<!-- 1)最好在ehcache.xml中声明不进行updateCheck -->
<!-- 2)为了配合BigMemory和Size Limit,原来的属性最好改名 -->
<!--   maxElementsInMemory->maxEntriesLocalHeap -->
<!--   maxElementsOnDisk->maxEntriesLocalDisk -->
<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
            maxElementsInMemory="1000"
            eternal="false"
            timeToIdleSeconds="60"
            timeToLiveSeconds="60"
            overflowToDisk="false"/>
    <cache name="myCache"
           maxElementsOnDisk="20000"
           maxElementsInMemory="2000"
           eternal="true"
           overflowToDisk="true"
           diskPersistent="true"/>

    <cache name="myCache2"
           maxElementsOnDisk="20000"
           maxElementsInMemory="2000"
           eternal="true"
           overflowToDisk="true"
           diskPersistent="true"/>
</ehcache>
<!--
<diskStore>==========当内存缓存中对象数量超过maxElementsInMemory时,将缓存对象写到磁盘缓存中(需对象实现序列化接口)
<diskStore path="">==用来配置磁盘缓存使用的物理路径,Ehcache磁盘缓存使用的文件后缀名是*.data和*.index
name=================缓存名称,cache的唯一标识(ehcache会把这个cache放到HashMap里)
maxElementsOnDisk====磁盘缓存中最多可以存放的元素数量,0表示无穷大
maxElementsInMemory==内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况
                     1)若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中
                     2)若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素
eternal==============缓存中对象是否永久有效,即是否永驻内存,true时将忽略timeToIdleSeconds和timeToLiveSeconds
timeToIdleSeconds====缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,此为可选属性
                     即访问这个cache中元素的最大间隔时间,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除
timeToLiveSeconds====缓存数据在失效前的允许存活时间(单位:秒),仅当eternal=false时使用,默认值是0表示可存活时间无穷大
                     即Cache中的某元素从创建到清楚的生存时间,也就是说从创建开始计时,当超过这个时间时,此元素将从Cache中清除
overflowToDisk=======内存不足时,是否启用磁盘缓存(即内存中对象数量达到maxElementsInMemory时,Ehcache会将对象写到磁盘中)
                     会根据标签中path值查找对应的属性值,写入磁盘的文件会放在path文件夹下,文件的名称是cache的名称,后缀名是data
diskPersistent=======是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件
                     这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存
                     要想把cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法
diskExpiryThreadIntervalSeconds==磁盘缓存的清理线程运行间隔,默认是120秒
diskSpoolBufferSizeMB============设置DiskStore(磁盘缓存)的缓存区大小,默认是30MB
memoryStoreEvictionPolicy========内存存储与释放策略,即达到maxElementsInMemory限制时,Ehcache会根据指定策略清理内存
                                 共有三种策略,分别为LRU(最近最少使用)、LFU(最常用的)、FIFO(先进先出)
-->
  • 修改springmvc.xml文件

图片alt

4、通过注解使用ehcache

  • 服务接口
package com.shenmazong.zg2.service;

import java.util.HashMap;

/**
 * @author 军哥
 * @version 1.0
 * @description: 缓存接口
 * @date 2023/10/15 19:24
 */

public interface EhCacheService {
    public HashMap<String, Object> createCache(String key, String value);
    public HashMap<String, Object> getCache(String key);
    public void delCache(String key);
}
  • 服务接口实现
package com.shenmazong.zg2.service.impl;

import com.shenmazong.zg2.service.EhCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.HashMap;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2023/10/15 19:26
 */

@Service
@Slf4j
public class EhCacheServiceImpl implements EhCacheService {
    @Override
    @Cacheable(value = "myCache", key = "'EhCacheServiceImpl'+#key")
    public HashMap<String, Object> createCache(String key, String value) {

        log.info("createCache:"+key+"~~~~~");


        HashMap<String, Object> map = new HashMap<>();

        map.put("name", "冯刚刚");
        map.put("age", "18岁");
        map.put(key, value);

        return map;
    }

    @Override
    @Cacheable(value = "myCache", key = "'EhCacheServiceImpl'+#key")
    public HashMap<String, Object> getCache(String key) {
        return null;
    }

    @Override
    @CacheEvict(value = "myCache", key = "'EhCacheServiceImpl'+#key")
    public void delCache(String key) {
        log.info("delCache:"+key+"~~~~~");
        return;
    }
}
  • 缓存控制层
package com.shenmazong.zg2.controller;

import com.shenmazong.zg2.service.EhCacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 军哥
 * @version 1.0
 * @description: 缓存控制类
 * @date 2023/10/15 19:46
 */

@RestController
@RequestMapping(value = "/cache")
public class EhCacheController {

    @Autowired
    EhCacheService ehCacheService;

    @PostMapping(value = "/create")
    public Object create() {
        return ehCacheService.createCache("name", "张飞");
    }

    @PostMapping(value = "/get")
    public Object get() {
        return ehCacheService.getCache("name");
    }

    @PostMapping(value = "/delete")
    public Object delete() {
        ehCacheService.delCache("name");

        return "OK";
    }

}
  • 删除所有缓存
    @Override
    @CacheEvict(value = "myCache", allEntries = true)
    public void delCacheAll() {
        
    }

5、通过注解使用ehcache

package com.shenmazong.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@Slf4j
@RequestMapping(value = "/eh")
public class EhController {

    @Autowired
    EhCacheCacheManager cacheManager;

    /**
     * 放入缓存
     * @param code
     * @return
     */
    @GetMapping(value = "/put")
    @ResponseBody
    public Object put(@RequestParam("code") String code) {
        cacheManager.getCache("myCache").put("userCode", code);
        return "OK";
    }

    /**
     * 从缓存中取数据
     * @return
     */
    @GetMapping(value = "/get")
    @ResponseBody
    public Object get() {

        String userCode = cacheManager.getCache("myCache").get("userCode", String.class);
        if(userCode != null) {
            System.out.println(userCode);
            return userCode;
        }

        return "NO DATA";
    }

    /**
     * 从缓存中删除数据
     * @return
     */
    @GetMapping(value = "/del")
    @ResponseBody
    public Object del() {
        cacheManager.getCache("myCache").evict("userCode");
        return "OK";
    }

    /**
     * 删除所有缓存
     * @return
     */
    @GetMapping(value = "/delAll")
    public Object delAll() {
        cacheManager.getCache("myCache").clear();

        return "OK";
    }

}

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

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

相关文章

红队专题-Golang工具ChYing

Golang工具ChYing 招募六边形战士队员原chying工具代码分析并发访问控制并发 原子 写入读取 通道嵌套映射结构初始化启动代理服务器重启代理服务器 招募六边形战士队员 一起学习 代码审计、安全开发、web攻防、逆向等。。。 私信联系 原chying工具代码分析 前有 Chying 后有…

什么是云服务器,阿里云优势如何?

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云百科aliyunbai…

C++|44.智能指针

文章目录 智能指针unique_ptr特点一——无法进行复制 shared_ptr特点一——可复制特点二——计数器&#xff08;用于确定删除的时机&#xff09; 其他 智能指针 通常的指针是需要特殊地去申请对应的空间&#xff0c;并在不使用的时候还需要人工去销毁。 而智能指针相对普通的指…

2024 1.6~1.12 周报

一、上周工作 论文研读 二、本周计划 思考毕业论文要用到的方法或者思想&#xff0c;多查多看积累可取之处。学习ppt和上周组会内容、卷积神经网络。 三、完成情况 1. 数据训练的方式 1.1 迁移学习 迁移学习是一种机器学习方法&#xff0c;把任务 A 训练出的模型作为初始模…

Java8常用新特性

目录 简介 1.默认方法 2..Lambda表达式 3.Stream API 4.方法引用 5.Optional类 简介 Java 8是Java编程语言的一个重要版本&#xff0c;引入了许多令人兴奋和强大的新特性。这些特性使得Java程序更加现代化、灵活和高效。让我们一起来探索一些Java 8的常用新特性吧&#…

css3基础语法与盒模型

css3基础语法与盒模型 前言CSS3基础入门css3的书写位置内嵌式外链式导入式&#xff08;工作中几乎不用&#xff09;行内式 css3基本语法css3选择器标签选择器id选择器class类名原子类复合选择器伪类元素关系选择器序号选择器属性选择器css3新增伪类![在这里插入图片描述](https…

【Java SE语法篇】6.数组

&#x1f4da;博客主页&#xff1a;爱敲代码的小杨. ✨专栏&#xff1a;《Java SE语法》 ❤️感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;&#xff0c;您的三连就是我持续更新的动力❤️ 文章目录 1.数组的基本概念1.1 为什么使用数组&#xff1f;1.…

如何一键添加引号和英文逗号,然后可以放入SQL中使用 → WHERE USER_NAME IN (‘张三‘,‘李四‘,‘王五‘)

如何一键添加引号和英文逗号&#xff0c;然后可以放入SQL中使用 → WHERE USER_NAME IN&#xff08;张三,李四,王五&#xff09; 一、背景二、解决方法三、一键添加引号和英文逗号的教程 一、背景 在日常开发中&#xff0c;当处理VARCHAR或VARCHAR2类型的字段时&#xff0c;很…

【Linux实用篇】Linux常用命令(1)

目录 1.1 Linux命令初体验 1.1.1 常用命令演示 1.1.2 Linux命令使用技巧 1.1.3 Linux命令格式 1.2 文件目录操作命令 1.2.1 ls 1.2.2 cd 1.2.3 cat 1.2.4 more 1.2.5 tail 1.2.6 mkdir 1.2.7 rmdir 1.2.8 rm 1.1 Linux命令初体验 1.1.1 常用命令演示 在这一部分中…

关于鸿蒙的ArkUI的自我理解

先不说好不好上手 一些软件必要的基础概念了解 ①瓦片地图 --无或未找到 ②视频播放功能 --未找到能播放直播流&#xff08;找到个 ohos/ijkplayer不知如何&#xff09; ③支付功能 微信无 支付宝的是java代码写得&#xff0c;AskUI中如何调用 ④推送 --自己应该有吧 ⑤长…

influxdb: 元数据操作

一、写语法 https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_tutorial/ 二、字段类型 https://docs.influxdata.com/influxdb/v1.7/write_protocols/line_protocol_reference/ 获取库下的表列表 SHOW MEASUREMENTS [ON <database_name>]…

MySQL的Windows系统安装

一、MySQL的Windows系统安装 1、下载MySQL安装包 打开如下链接地址&#xff0c;下载安装包 2、安装并配置 双击下载好的安装包进行安装&#xff0c;出现如下界面&#xff1a; 选择【 Full 】选项&#xff0c;然后单击【 Next 】按钮。 出现如下界面&#xff0c;单击【 Execute…

HCIA的交换机(单臂路由)

实现单臂路由的IP自动分配 实验素材&#xff1a; 实现思路&#xff1a; 交换机&#xff1a;创建VLAN10&#xff0c;VLAN20&#xff0c;将0/0/1&#xff0c;2划入相应VLAN&#xff0c;接口使用access模式&#xff0c; 要实现两个交换机之间的通信&#xff0c;须在0/0/3口使用t…

HTML 链接 图片引入

文章目录 链接图片引入 链接 准备工作 新建一个名为link.html和suc.html suc.html <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>显示结果</title></head><body>注册成功...&l…

springboot+ipage分页频繁请求会报错 自动添加多一个limit

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near LIMIT 500 at line 3 这个原因是因为springboot配置mysql的连接池太…

2024阿里云服务器ECS介绍_全方位解析_CPU性能详解

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云百科aliyunbai…

HTTP 常见协议:选择正确的协议,提升用户体验(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

「Qt Widget中文示例指南」如何实现一个日历?(二)

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写&#xff0c;所有平台无差别运行&#xff0c;更提供了几乎所有开发过程中需要用到的工具。如今&#xff0c;Qt已被运用于超过70个行业、数千家企业&#xff0c;支持数百万设备及应用。 本文中的CalendarWi…

UG装配-多运动组合动画与自动创建装配路径

当圆盘在装配过程中既有旋转运动&#xff0c;又有直线运动的时候&#xff0c;我们需要用到序列中的抽取路径 抽取路径命令在如下位置&#xff0c;需要注意的是&#xff0c;使用抽取路径前&#xff0c;如果有其他零件与所取对象配合&#xff0c;需要先物体脱离或使用拆卸对其脱离…

什么情况下考虑同时接入SD-WAN与MPLS

在企业网络架构中&#xff0c;SD-WAN和MPLS&#xff08;多协议标签交换&#xff09;都是常见的网络连接解决方案。而有时候&#xff0c;企业可能面临一种情况&#xff0c;即需要同时接入SD-WAN和MPLS。本文将探讨在什么情况下考虑同时使用这两种网络连接方式&#xff0c;并分析…