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

SpringBoot整合缓存1-Ehcache

一、缓存是什么?

缓存是一种将数据临时存储在高速存储介质(如内存)中的技术,目的是减少对数据库等低速存储的访问,提升系统响应速度。

Ehcache 是一个成熟的 Java 缓存框架,支持本地缓存分布式缓存(需配合 Terracotta 服务器),具备轻量、高效、可配置性强等特点。它是 Spring Cache 默认支持的缓存实现之一,通过 XML 或注解配置缓存策略(如过期时间、最大容量等),可直接与 Spring 生态整合。

二、选择 Ehcache 的优势

  1. 成熟稳定:作为老牌缓存框架,广泛应用于企业级项目,兼容性强。
  2. 灵活配置:支持通过 XML 精细定义缓存策略(如堆内 / 堆外存储、过期规则)。
  3. 本地缓存优先:无需额外部署服务(如 Redis),适合单体应用或对分布式缓存需求较低的场景。
  4. 与 Spring 无缝整合:通过 Spring Cache 注解即可快速使用,无需手动编写缓存逻辑。

三、案例实现过程

image-20251024180917975

以「图书管理系统」为例,实现图书信息的增删改查,并通过 Ehcache 缓存高频查询数据(如图书详情),减少数据库访问次数。

核心需求:查询图书时优先从缓存获取,新增 / 更新图书时同步更新缓存,删除图书时清除对应缓存。

1. 技术栈

  • SpringBoot 2.7.x:快速开发框架,简化配置
  • Ehcache 2.x:Java 本地缓存框架,支持自定义缓存策略(过期时间、容量等)
  • MyBatis-Plus 3.5.x:MyBatis 增强工具,简化 CRUD 操作
  • MySQL:关系型数据库(提供建表 SQL)

2.创建 Maven 项目Ehcache-Demo,配置 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.yqd</groupId><artifactId>Ehcache-Demo</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>Ehcache-Demo</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- SpringBoot Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 缓存抽象层 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!-- Ehcache 2.x 缓存实现 --><dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId></dependency><!-- MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!-- Lombok(简化实体类) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3. 配置文件

(1)Ehcache 配置(src/main/resources/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"><!-- 磁盘缓存位置(可选,本地缓存溢出时使用) --><diskStore path="java.io.tmpdir/ehcache"/><!-- 默认缓存配置(可选,未指定缓存策略时使用) --><defaultCache maxEntriesLocalHeap="1000"eternal="false"timeToIdleSeconds="60"timeToLiveSeconds="60"overflowToDisk="false"/><!-- 图书缓存策略(需与@CacheConfig的cacheNames对应) --><cache name="bookCache"maxEntriesLocalHeap="200"eternal="false"timeToIdleSeconds="0"timeToLiveSeconds="60"overflowToDisk="false"/>
</ehcache>

(2)应用配置(src/main/resources/application.yml)

spring:# 数据库配置datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/book_cache_demo?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=trueusername: root  # 替换为你的MySQL用户名password: 123456  # 替换为你的MySQL密码# 缓存配置(指定Ehcache)cache:type: ehcacheehcache:config: classpath:ehcache.xml  # 加载自定义缓存策略# MyBatis-Plus配置
mybatis-plus:mapper-locations: classpath:mapper/*.xml  # Mapper.xml路径type-aliases-package: com.yqd.entity  # 实体类包路径configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 打印SQL,验证缓存是否生效

4. 代码实现

(1)实体类(com.example.entity.Book.java)
package com.yqd.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.math.BigDecimal;
import java.util.Date;@Data
@TableName("t_book")  // 对应数据库表t_book(MyBatis-Plus已配置table-prefix: t_)
public class Book {@TableId(type = IdType.AUTO)private Long id;private String bookName;  // 图书名称(对应数据库book_name)private String author;    // 作者private Date publishTime; // 出版时间private BigDecimal price; // 价格
}
(2)Mapper 接口(com.example.mapper.BookMapper.java)
package com.yqd.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yqd.entity.Book;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface BookMapper extends BaseMapper<Book> {// 无需手动编写CRUD方法,BaseMapper已提供(selectById、insert、updateById、deleteById等)
}
(3)Service 层(com.example.service.BookService.java)
package com.yqd.service;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yqd.entity.Book;
import com.yqd.mapper.BookMapper;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;@Service
@CacheConfig(cacheNames = "bookCache")  // 绑定ehcache.xml中的bookCache
public class BookService extends ServiceImpl<BookMapper, Book> {// 查询图书:缓存key=bookCache::id@Cacheable(key = "#id")public Book getById(Long id) {System.out.println("【数据库查询】id=" + id);  // 用于验证缓存是否生效return baseMapper.selectById(id);}// 新增图书:缓存key=bookCache::新增图书的id@CachePut(key = "#result.id")public Book add(Book book) {baseMapper.insert(book);return book;}// 更新图书:缓存key=bookCache::book.id@CachePut(key = "#book.id")public Book update(Book book) {baseMapper.updateById(book);return book;}// 删除图书:清除bookCache::id的缓存@CacheEvict(key = "#id")public void delete(Long id) {baseMapper.deleteById(id);}// 清除所有缓存@CacheEvict(allEntries = true)public void clearAll() {System.out.println("【清除所有缓存】");}
}
(4)Controller 层(com.example.controller.BookController.java)
package com.yqd.controller;import com.yqd.entity.Book;
import com.yqd.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/books")
public class BookController {@Autowiredprivate BookService bookService;// 查询图书@GetMapping("/{id}")public Book get(@PathVariable Long id) {return bookService.getById(id);}// 新增图书@PostMappingpublic Book add(@RequestBody Book book) {return bookService.add(book);}// 更新图书@PutMappingpublic Book update(@RequestBody Book book) {return bookService.update(book);}// 删除图书@DeleteMapping("/{id}")public String delete(@PathVariable Long id) {bookService.delete(id);return "删除成功";}// 清除所有缓存@DeleteMapping("/clear")public String clear() {bookService.clearAll();return "所有缓存已清除";}
}
(5)启动类(com.example.EhcacheDemoApplication.java)
package com.yqd;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication
@EnableCaching  // 开启Spring缓存功能
@MapperScan("com.yqd.mapper")  // 扫描Mapper接口
public class EhcacheDemo {public static void main(String[] args) {SpringApplication.run(EhcacheDemo.class, args);}
}

四、测试过程(使用 apipost或浏览器)

1. 新增图书
  • 请求POST http://localhost:8080/books

  • Body(JSON):

    {"bookName": "Java编程思想","author": "Bruce Eckel","publishTime": "2007-06-01","price": 108.00
    }
    
  • 响应:返回新增的图书信息(包含自增 ID,例如id=1)。

2. 测试查询缓存
  • 首次查询GET http://localhost:8080/books/1
    • 控制台输出:【数据库查询】id=1(走数据库)。
    • 响应:返回图书信息。
  • 再次查询GET http://localhost:8080/books/1
    • 控制台无输出(走缓存)。
    • 响应:返回相同图书信息,速度更快。
3. 测试缓存更新
  • 更新图书PUT http://localhost:8080/books

    • Body(JSON):

      {"id": 1,"bookName": "Java编程思想(第4版)","author": "Bruce Eckel","publishTime": "2007-06-01","price": 128.00
      }
      
  • 查询验证GET http://localhost:8080/books/1

    • 响应:返回更新后的价格(128.00),说明缓存已同步更新。
4. 测试缓存过期
  • 等待 60 秒(ehcache.xml 中配置的timeToLiveSeconds=60)。

  • 再次查询:

    GET http://localhost:8080/books/1
    
    • 控制台重新输出:【数据库查询】id=1(缓存过期,重新查库)。
5. 测试缓存删除
  • 删除图书DELETE http://localhost:8080/books/1

  • 查询验证:

    GET http://localhost:8080/books/1
    
    • 响应:null(数据库记录已删除,缓存也被清除)。
6. 测试清除所有缓存
  • 新增另一本图书(例如id=2),并查询确保缓存生效。
  • 清除缓存:DELETE http://localhost:8080/books/clear
  • 查询id=2的图书:控制台输出【数据库查询】id=2(缓存已被清除)。

五、预期结果

  • 首次查询走数据库,后续查询走缓存(无数据库日志)。
  • 更新操作后,缓存同步更新为新数据。
  • 缓存过期或删除后,查询重新走数据库。
  • 清除所有缓存后,所有查询均重新走数据库。
http://www.hskmm.com/?act=detail&tid=38291

相关文章:

  • 【开题答辩全过程】以 M11289生鲜商城为例,具备答辩的问题和答案
  • ZR 2025 NOIP 二十连测 Day 7
  • CSP-S 37
  • Offsec Nibbles CTF 实战解析:PostgreSQL漏洞利用与权限提升
  • 如何在一台 Linux 机器上管理不同版本的 CMake
  • 90 天打造可持续交付:12 条 DevOps 实践要点与避坑
  • CSharp: word,excel,powerpoint convert to pdf,hrml etc using Aspose.Office
  • 2025年新疆喀纳斯旅游服务权威推荐榜单:新疆/阿勒泰/禾木深度游旅行社综合评测
  • 一天一款实用的AI工具,第9期,AI转黏土风格
  • 2025 10 24日报
  • 题解:P8930 「TERRA-OI R1」神,不惧死亡
  • 2025 OSCAR丨与创新者同频!Apache RocketMQ 邀您共赴开源之约
  • 生产环节最容易出问题的三个点,老板必须盯紧
  • 2025年PSA制氮设备厂家权威推荐榜单:电解水制氢设备/氦气纯化系统/氘气回收纯化源头厂家精选
  • 解决git clone只有master分支的问题
  • 一文读懂循环神经网络(RNN):原理、局限与LSTM解决方案 - 指南
  • 2025年搬家纸箱权威推荐榜单:物流包装/电商纸箱/平口纸箱源头厂家精选
  • 大数据案例 -2025/10/24
  • 2025年阳台壁挂太阳能厂家权威推荐榜单:分体式阳台太阳能/阳台壁挂太阳能热水器/分体式阳台太阳能源头厂家精选
  • 使用C# 控制ethercat从站设备
  • 从价值直觉到价值理性:AI元人文演进路径解读
  • 0269-GRPC-使用 prost 编码
  • 0268-GRPC-prost 生成文件到目录
  • 0271-GRPC-prost 带长度的编解码
  • 2025 年坡口机源头厂家最新推荐排行榜:欧盟 CE 认证企业领衔,含 15 年工业服务经验品牌,自走式/自动/板材/管道坡口机厂家推荐
  • 0270-GRPC-使用 prost 解码
  • 完整教程:Java开发者进阶之路
  • 动手动脑4
  • python+request+unittest自动化测试
  • 2025 年保温涂料厂家最新推荐排行榜:聚焦技术专利与管理体系认证的优质品牌耐高温/防火耐热/防腐/纳米介孔微珠中空粒子保温涂料公司推荐