SpringBoot集成cache缓存的实现

作者:huanzi-qch 时间:2023-11-27 16:37:39 

前言

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

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

工程结构

SpringBoot集成cache缓存的实现

代码编写

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代码

SpringBoot集成cache缓存的实现


@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对象的数据被缓存下来

SpringBoot集成cache缓存的实现

SpringBoot集成cache缓存的实现

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

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

SpringBoot集成cache缓存的实现

SpringBoot集成cache缓存的实现

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

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

SpringBoot集成cache缓存的实现

SpringBoot集成cache缓存的实现

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

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

SpringBoot集成cache缓存的实现

SpringBoot集成cache缓存的实现

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

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

SpringBoot集成cache缓存的实现

SpringBoot集成cache缓存的实现

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

SpringBoot集成cache缓存的实现

http://localhost:10010/tbUser/list

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

SpringBoot集成cache缓存的实现

SpringBoot集成cache缓存的实现

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

SpringBoot集成cache缓存的实现

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

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

SpringBoot集成cache缓存的实现

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

来源:https://www.cnblogs.com/huanzi-qch/p/14871341.html

标签:SpringBoot,cache,缓存
0
投稿

猜你喜欢

  • Android编程实现的短信编辑器功能示例

    2022-09-08 12:58:44
  • Android编程中EditText限制文字输入的方法

    2023-07-19 07:30:48
  • 使用logback实现按自己的需求打印日志到自定义的文件里

    2022-05-12 16:56:49
  • OnSharedPreferenceChangeListener详解及出现不触发解决办法

    2021-10-25 19:06:36
  • Android实现在屏幕上移动图片的方法

    2022-06-03 01:40:26
  • Java Maven settings.xml中私有仓库配置详解

    2022-02-19 15:36:50
  • Android 屏幕切换监听的实例代码

    2023-07-03 13:00:19
  • mybatis的插件机制示例详解

    2023-02-24 23:46:17
  • Android recyclerview实现拖拽排序和侧滑删除

    2021-10-04 00:33:16
  • ssm mybatis如何配置多个mapper目录

    2021-12-06 14:08:25
  • OpenGL绘制三次Bezier曲线

    2022-04-23 18:18:14
  • 详解c#与python的交互方式

    2023-12-13 09:16:11
  • Java实现英文猜词游戏的示例代码

    2023-08-07 11:40:39
  • 详解Mybatis通用Mapper介绍与使用

    2023-11-29 08:49:08
  • c#调用arcgis地图rest服务示例详解(arcgis地图输出)

    2023-03-05 14:56:05
  • MyBatis全局配置文件详解

    2021-09-19 10:13:32
  • FragmentStatePagerAdapter保存恢复下拉刷新Fragment内存数据

    2023-07-17 20:36:40
  • C#实现围棋游戏

    2022-04-20 11:08:57
  • Java 归并排序算法、堆排序算法实例详解

    2023-11-25 09:43:25
  • Spring Boot支持Crontab任务改造的方法

    2023-08-08 20:20:24
  • asp之家 软件编程 m.aspxhome.com