前言

  日常开发中,缓存是解决数据库压力的一种方案,通常用于频繁查询的数据,例如新闻中的热点新闻,本文记录springboot中使用cache缓存。

  官方文档介绍:https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-caching-provider-generic

  

  工程结构

  代码编写

  pom引入依赖,引入cache缓存,数据库使用mysql,ORM框架用jpa

        <!--添加springdata-cache依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency> <!-- 引入ehcache支持 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency> <!--添加springdata-jpa依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> <!--添加MySQL驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

  配置文件

server.port=10010
spring.application.name=springboot-cache spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:/ehcache.xml

  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"/> <!-- maxEntriesLocalHeap:堆内存中最大缓存对象数,0没有限制 -->
<!-- maxElementsInMemory: 在内存中缓存的element的最大数目。-->
<!-- eternal:elements是否永久有效,如果为true,timeouts将被忽略,element将永不过期 -->
<!-- timeToIdleSeconds:发呆秒数,发呆期间未访问缓存立即过期,当eternal为false时,这个属性才有效,0为不限制 -->
<!-- timeToLiveSeconds:总存活秒数,当eternal为false时,这个属性才有效,0为不限制 -->
<!-- overflowToDisk: 如果内存中数据超过内存限制,是否要缓存到磁盘上 -->
<!-- statistics:是否收集统计信息。如果需要监控缓存使用情况,应该打开这个选项。默认为关闭(统计会影响性能)。设置statistics="true"开启统计 --> <!--
默认缓存
无过期时间,但 600 秒内无人访问缓存立即过期
-->
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="600"
timeToLiveSeconds="0"
overflowToDisk="false">
</defaultCache> <!--
xx业务缓存
在有效的 120 秒内,如果连续 60 秒未访问缓存,则缓存失效。
就算有访问,也只会存活 120 秒。
-->
<cache name="myCache"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="0"
overflowToDisk="false">
</cache>
</ehcache>

  先写一个套tb_user表的CRUD代码

@RestController
@RequestMapping("/tbUser/")
public class TbUserController {
@Autowired
private TbUserService tbUserService; //方便测试暂时改成GetMapping
@GetMapping("list")
// @PostMapping("list")
public List<TbUser> list(TbUser entityVo) {
return tbUserService.list(entityVo);
} @GetMapping("get/{id}")
public TbUser get(@PathVariable("id")Integer id) {
return tbUserService.get(id);
} //方便测试暂时改成GetMapping
@GetMapping("save")
// @PostMapping("save")
public TbUser save(TbUser entityVo) {
return tbUserService.save(entityVo);
} @GetMapping("delete/{id}")
public Integer delete( @PathVariable("id") Integer id) {
return tbUserService.delete(id);
}
}

  opjo实体类要实现序列化

@Entity
@Table(name = "tb_user")
@Data
public class TbUser implements Serializable {
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;//表id private String username;//用户名 private String password;//密码 private Date created;//创建时间 private Integer descriptionId;//关联详情id
}

  serviceImpl中,使用注解来开启缓存

@Service
@Transactional
@CacheConfig(cacheNames = {"myCache"})
public class TbUserServiceImpl implements TbUserService{ @PersistenceContext
private EntityManager em; @Autowired
private TbUserRepository tbUserRepository; //@Cacheable缓存数据:key为userList,value为返回值List<TbUser>
@Cacheable(key = "'userList'")
@Override
public List<TbUser> list(TbUser entityVo) {
System.out.println("获取list用户列表缓存数据,"+new Date());
return tbUserRepository.findAll(Example.of(entityVo));
} //@Cacheable缓存数据:key为参数id,value为返回值TbUser
@Cacheable(key = "#id")
@Override
public TbUser get(Integer id) {
System.out.println("获取数据缓存,key:"+id);
Optional<TbUser> optionalE = tbUserRepository.findById(id);
if (!optionalE.isPresent()) {
throw new RuntimeException("ID不存在!");
}
return optionalE.get();
} //@CachePut缓存新增的或更新的数据到缓存,其中缓存的名称为people,数据的key是person的id
@CachePut(key = "#entityVo.id")
// @CacheEvict从缓存中删除key为参数userList的数据
@CacheEvict(key = "'userList'")
@Override
public TbUser save(TbUser entityVo) {
System.out.println("新增/更新缓存,key:"+entityVo.getId());
//entityVo传啥存啥,会全部更新
return tbUserRepository.save(entityVo);
} //清空所有缓存
@CacheEvict(allEntries=true)
@Override
public Integer delete(Integer id) {
System.out.println("清空所有缓存");
tbUserRepository.deleteById(id);
return id;
}
}

  效果演示

  http://localhost:10010/tbUser/save?id=2&username=李四

  调用save方法,key为2,value为当前tbUser对象的数据被缓存下来

  

  http://localhost:10010/tbUser/get/2

  当我们调用get方法时,直接获取缓存数据,控制台啥也不打印,连serviceImpl的get方法都不进去(可以打断点调试)

  

  http://localhost:10010/tbUser/save?id=2&username=王五

  当我们再次调用save方法更新username时,缓存数据也被更新

  http://localhost:10010/tbUser/get/2

  再次调用get接口,直接返回缓存数据,后台也是方法都不进去,啥也不打印

  http://localhost:10010/tbUser/delete/2

  调用delete接口,删除数据,同时删除缓存

  再次调用get接口,发现缓存数据被清除,查询数据库

  http://localhost:10010/tbUser/list

  首次调用list接口,key为userList的,value为用户集合数据被缓存下来,再次调用直接返回缓存数据

  当调用save接口,数据更新,删除key为userList的缓存,再次调用list时,重新查库并设置缓存

  我们配置了缓存发呆时间,当120秒内未使用该缓存,立即过期,一直用就会一直存在

  我们先同时访问两个接口list、get,list接口2分钟后再次访问,get接口不能超过2分钟是不是访问一下,结果如预期

  PS:原先使用了这个jar包,有报错

    <dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.8.1</version>
</dependency>

  后面改成用上面“代码编写”里pom中引的jnet.sf.ehcache下面的ar

  后记

  缓存除了能缓解数据库压力,还能做用户登录状态控制,例如:用户登录成功后cookie中保存颁发的token令牌设置永不过期,缓存存活时间也设置永不过期,发呆时间设置1天,这样只有用户在1天内有访问缓存接口,那他就可以一直保留登录状态,直至有其他业务将token或者缓存清掉。

  springboot使用cache缓存暂时先记录到这,后续有空再进行补充。

  代码开源

  代码已经开源、托管到我的GitHub、码云:

  GitHub:https://github.com/huanzi-qch/springBoot

  码云:https://gitee.com/huanzi-qch/springBoot

SpringBoot系列——cache缓存的更多相关文章

  1. SpringBoot日记——Cache缓存篇

    通常我们访问数据的情况如下图,数据存缓存就取缓存,不存缓存就取数据库,这样可以提升效率,不用一直读取数据库的信息: 开始记录: 关于SpringBoot缓存的应用 1. 首先在pom.xml文件中添加 ...

  2. springboot(九) Cache缓存和Redis缓存

    1. Cache缓存 1.1 缓存的概念&缓存注解 Cache 缓存接口,定义缓存操作.实现有:RedisCache.EhCacheCache.ConcurrentMapCache等 Cach ...

  3. SpringBoot系列之缓存使用教程

    介绍SpringBoot项目中使用缓存,之前先介绍一下Spring的缓存抽象和JSR107,本博客是我在学习尚硅谷视频和参考其它博客之后做的笔记,仅供学习参考 @ 目录 一.Spring的缓存抽象 1 ...

  4. 深度理解springboot集成cache缓存之源码解析

    一.案例准备 1.创建数据表(employee表) 2.创建Employee实体类封装数据库中的数据 @AllArgsConstructor @NoArgsConstructor @Data @ToS ...

  5. Springboot使用ehcache缓存

    本文部分步骤继承于springboot使用cache缓存,如果有不清楚的,请移驾springboot使用cache缓存 ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存,Java ...

  6. SpringBoot系列:Spring Boot集成Spring Cache,使用EhCache

    前面的章节,讲解了Spring Boot集成Spring Cache,Spring Cache已经完成了多种Cache的实现,包括EhCache.RedisCache.ConcurrentMapCac ...

  7. Ajax跨域问题及解决方案 asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS) c#中的Cache缓存技术 C#中的Cookie C#串口扫描枪的简单实现 c#Socket服务器与客户端的开发(2)

    Ajax跨域问题及解决方案   目录 复现Ajax跨域问题 Ajax跨域介绍 Ajax跨域解决方案 一. 在服务端添加响应头Access-Control-Allow-Origin 二. 使用JSONP ...

  8. springboot系列:使用缓存

    前言:springboot已经为我们实现了抽象的api接口,因此当我们使用不同的缓存时,只是配置有可能有点区别(比如ehcache和Redis),但是在程序中使用缓存的方法是一样的. 1.spring ...

  9. 【快学SpringBoot】快速上手好用方便的Spring Cache缓存框架

    前言 缓存,在开发中是非常常用的.在高并发系统中,如果没有缓存,纯靠数据库来扛,那么数据库压力会非常大,搞不好还会出现宕机的情况.本篇文章,将会带大家学习Spring Cache缓存框架. 原创声明 ...

随机推荐

  1. Hydra暴力破解工具的用法

    目录 Hydra 常见参数 破解SSH 破解FTP 破解HTTP 破解3389远程登录 Kali自带密码字典 dirb dirbuster fern-wifi metasploit wfuzz Hyd ...

  2. POJ1325二分匹配或者DINIC(最小路径覆盖)

    题意:        有k个任务,两个机器,第一个机器有n个模式,第二个机器有m个模式,每个任务要么在第一个机器的一个模式下工作,要么在第二个机器的一个模式下工作,机器每切换一个模式需要重启一次,两个 ...

  3. UVA11375火柴(递推+大数)

    题意:       给你n根火柴,问你能组成多少种数字,比如3根可以组成1或者7,组成的数字中不能有前导0, 思路:       我们开一个数组,d[i]记录用i跟火柴可以组成多少种数字,则更新状态是 ...

  4. seccomp沙盒逃逸基础——沙盒的规则编写

    seccomp沙盒逃逸基础--沙盒的规则编写 引入: 安全计算模式 seccomp(Secure Computing Mode)是自 Linux 2.6.10 之后引入到 kernel 的特性.一切都 ...

  5. TCP的握手和挥手

    三次握手 三次握手具体过程是什么? 客户端发送一个数据包 将SYN置成1,表示希望建立连接 这个包中的序列号是X 服务器收到客户端发来的数据包 通过SYN得知这是一个建立连接的请求 于是发送一个响应包 ...

  6. webpack 快速入门 系列 —— 初步认识 webpack

    初步认识 webpack webpack 是一种构建工具 webpack 是构建工具中的一种. 所谓构建,就是将资源转成浏览器可以识别的.比如我们用 less.es6 写代码,浏览器不能识别 less ...

  7. BUAA-OO-第三单元总结

    面向对象第三单元JML总结 JML理论基础及工具链梳理 JML语言理论基础 JML语言是对于JAVA进行规格化设计的一种表述语言,他能以一种统一化语言,逻辑性强的格式,向程序设计者描述这一方法实现的功 ...

  8. Xshell 远程使用vim打开文件不能使用右键复制粘贴(右键显示可视)的问题

    Xshell 远程使用vim打开文件不能使用右键复制粘贴(右键显示可视)的问题 Debian9.4系统不能再VIM打开文件界面不能使用右键复制粘贴 root@debian:~# vim /usr/sh ...

  9. 查询登录信息 w, who*, id, tty, last, finger

    查询登录信息 w, who*, id, tty, last, finger Wavky2016.12.14 16:19:37字数 813阅读 85w [options] [user...]显示所有已登 ...

  10. shell基础之多功能nginx(安装、重启、停止等)

    1 #!/bin/bash 2 #要求:检查本机是否已编译安装nginx,检查本机是否存在nginx源码包,编译安装nginx,实现开启.停止.查看状态等功能 3 #检查是否已编译安装nginx 4 ...