关注公众号【江南一点雨】,专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!


春节就要到了,在回家之前要赶快把今年欠下的技术债还清。so,今天继续。Spring Boot前面已经预热了n篇博客了,今天我们来继续看如何在Spring Boot中解决数据缓存问题。本篇博客是以初识在Spring Boot中使用JPA为基础的,先了解如何实现数据访问,然后才好实现数据缓存。OK,对于Spring Boot尚有疑问的小伙伴可以先移步这里从SpringMVC到Spring Boot,老司机请略过。
OK,废话不多说,开始今天的技术之旅吧。
在实际开发中,对于要反复读写的数据,最好的处理方式是将之在内存中缓存一份,频繁的数据库访问会造成程序效率低下,同时内存的读写速度本身就要强于硬盘。Spring在这一方面给我们提供了诸多的处理手段,而Spring Boot又将这些处理方式进一步简化,接下来我们就来看看如何在Spring Boot中解决数据缓存问题。


#创建Project并添加数据库驱动
Spring Boot的创建方式还是和我们前文提到的创建方式一样,不同的是这里选择添加的依赖不同,这里我们添加Web、Cache和JPA依赖,如下图:

创建成功之后,接下来添加数据库驱动,我还是使用MySql,在pom.xml中添加数据库驱动,如下:

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.40</version></dependency>

#配置application.properties
这个application.properties的配置还是和初识在Spring Boot中使用JPA一样,各个参数的含义我这里也不再赘述,我们直接来看代码:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sang?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=sangspring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jackson.serialization.indent_output=true

#创建实体类

@Entity
public class Person {@Id@GeneratedValueprivate Long id;private String name;private String address;private Integer age;public Person() {}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Person(Long id, String name, String address, Integer age) {this.id = id;this.name = name;this.address = address;this.age = age;}
}

#创建实体类的Repository

public interface PersonRepository extends JpaRepository<Person,Long> {
}

#创建业务类

业务接口

public interface DemoService {public Person save(Person person);public void remove(Long id);public Person findOne(Person person);
}

实现类

@Service
public class DemoServiceImpl implements DemoService {@AutowiredPersonRepository personRepository;@CachePut(value = "people", key = "#person.id")@Overridepublic Person save(Person person) {Person p = personRepository.save(person);System.out.println("为id、key为" + p.getId() + "数据做了缓存");return p;}@CacheEvict(value = "people")@Overridepublic void remove(Long id) {System.out.println("删除了id、key为" + id + "的数据缓存");personRepository.delete(id);}@Cacheable(value = "people", key = "#person.id")@Overridepublic Person findOne(Person person) {Person p = personRepository.findOne(person.getId());System.out.println("为id、key为" + p.getId() + "数据做了缓存");return p;}
}@Service
public class DemoServiceImpl implements DemoService {@AutowiredPersonRepository personRepository;@CachePut(value = "people", key = "#person.id")@Overridepublic Person save(Person person) {Person p = personRepository.save(person);System.out.println("为id、key为" + p.getId() + "数据做了缓存");return p;}@CacheEvict(value = "people")@Overridepublic void remove(Long id) {System.out.println("删除了id、key为" + id + "的数据缓存");personRepository.delete(id);}@Cacheable(value = "people", key = "#person.id")@Overridepublic Person findOne(Person person) {Person p = personRepository.findOne(person.getId());System.out.println("为id、key为" + p.getId() + "数据做了缓存");return p;}
}

关于这个实现类我说如下几点:

1.@CachePut表示缓存新添加的数据或者更新的数据到缓存中,两个参数value表示缓存的名称为people,key表示缓存的key为person的id
2.@CacheEvict表示从缓存people中删除key为id的数据
3.@Cacheable表示添加数据到缓存中,缓存名称为people,缓存key为person的id属性。


#创建Controller

@RestController
public class CacheController {@AutowiredDemoService demoService;@RequestMapping("/put")public Person put(Person person) {return demoService.save(person);}@RequestMapping("/able")public Person cacheable(Person person) {return demoService.findOne(person);}@RequestMapping("/evit")public String evit(Long id) {demoService.remove(id);return "ok";}
}

OK ,做完这一切我们就可以来测试我们刚刚写的缓存了。
#测试
看我们的Controller,我们有三个地址要测试,一个一个来。当然,在 测试之前,我们先来看看初始状态下的数据库是什么样子的:


首先我们在浏览器中访问http://localhost:8080/able?id=1,得到如下访问结果:

这个时候查看控制台,输出内容如下:

说是数据已经被缓存了,这个时候我们再继续在浏览器中刷新继续请求id为1的数据,会发现控制台不会继续打印日志出来,就是因为数据已被存于缓存之中了。


接下来我们向浏览器中输入http://localhost:8080/put?age=47&name=奥巴牛&address=米国,访问结果如下:

这个时候查看控制台打印的日志如下:

再查看数据表,数据已插入成功:

此时,我们在浏览器中输入http://localhost:8080/able?id=106,访问刚刚插入的这条数据,结果如下:

这个时候查看控制台,发现并没有数据数据,就是因为数据已经处于缓存中了。


最后我们在浏览器中输入http://localhost:8080/evit?id=106,将数据从缓存中移除,访问结果如下:

这个时候查看控制台,已经提示缓存移除掉了:

同时数据也从数据库删除掉了,这个时候如果还需要该数据则需要我们继续向表中添加数据。

#缓存技术切换
Spring Boot默认情况下使用ConcurrentMapCacheManager作为缓存技术,有的时候你可能想替换为其他的缓存方式,在Spring Boot中进行缓存的切换非常简单,我这里以Google提供的Guava为例,如果要使用这种缓存策略,只需要添加相应的依赖即可,如下:

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version>
</dependency>

就这样就可以了。实际上在Spring Boot中,底层使用哪一种缓存我们并不必做过多考虑,切换的方式也很简单,如上文引入相应的依赖即可,我们只需要把上层的逻辑写好即可。

本文案例下载:
本文GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test25-Cache.

更多Spring Boot案例请移步这里从SpringMVC到Spring Boot

以上。

参考资料:

《JavaEE开发的颠覆者 Spring Boot实战》第八章

在Spring Boot中使用数据缓存相关推荐

  1. SpringBoot : Spring Boot中使用数据缓存 spring-boot-starter-cache

    1.美图 2.概述 项目中经常会用到cache技术,Spring boot提供了方便的注解以便我们从重复的cache代码中解放出来. 首先得引入spring-boot-starter-cache这个j ...

  2. 第 4-4 课:Spring Boot 中使⽤ Cache 缓存的使⽤

    我们知道绝⼤多数的⽹站/系统,最先遇到的⼀个性能瓶颈就是数据库,使⽤缓存做数据库的前置缓存,可以 ⾮常有效地降低数据库的压⼒,从⽽提升整个系统的响应效率和并发量. 以往使⽤缓存时,通常创建好缓存⼯具类 ...

  3. flyway spring_关于使用Flyway在Spring Boot中管理数据更改的建议

    flyway spring 介绍 (Introduction) Database migrations are essential for the development of an applicat ...

  4. Spring Boot 中使⽤ Cache 缓存的使⽤

    1.美图 2.概述 我们知道绝⼤多数的⽹站/系统,最先遇到的一个性能瓶颈就是数据库,使⽤用缓存做数据库的前置缓存,可以非常有效地降低数据库的压力,从而提升整个系统的响应效率和并发量. 以往使⽤缓存时, ...

  5. Spring Boot中的缓存支持(二)使用Redis做集中式缓存

    上一篇介绍了在Spring Boot中如何引入缓存.缓存注解的使用.以及EhCache的整合. 虽然EhCache已经能够适用很多应用场景,但是由于EhCache是进程内的缓存框架,在集群模式下时,各 ...

  6. Spring Boot中的缓存支持(一)注解配置与EhCache使用

    随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决这一问题非常好的手段之一.Spring 3开始提供了强大的基于注解的缓 ...

  7. boot spring 接口接收数据_在 Spring Boot 中使用 Dataway 配置数据查询接口

    Dataway介绍 Dataway 是基于 DataQL 服务聚合能力,为应用提供的一个接口配置工具.使得使用者无需开发任何代码就配置一个满足需求的接口. 整个接口配置.测试.冒烟.发布.一站式都通过 ...

  8. 在Spring Boot中加载初始化数据

    文章目录 依赖条件 data.sql文件 schema.sql 文件 @sql注解 @SqlConfig 注解 在Spring Boot中加载初始化数据 在Spring Boot中,Spring Bo ...

  9. 使用Spring Security在Spring Boot中进行缓存

    在这篇文章中,我想分享一下O&B的一个团队的经验教训. 他们正在使用带有Spring Security的Spring Boot. 默认情况下,Spring Security保护的所有内容都将通 ...

最新文章

  1. UNP总结 Chapter 11 名字与地址转换
  2. 2021-05-10 Matlab短时傅里叶变换和小波变换的时频分析
  3. vim的配置安装和Python安装细节记录20190109
  4. tomcat服务器安装
  5. 常用的函数式接口_Supplier接口练习_求数组元素最大值
  6. Androd安全——反编译技术完全解析
  7. .Net Core开发日志——Global Tools
  8. 去小公司了解哪些工具?
  9. LTNS的完整形式是什么?
  10. 和为k的连续区间(51Nod-1094)
  11. ASP.NET MVC使用log4net
  12. RPM打包原理、示例、详解及备查( 转)
  13. TTL(UART)信号和RS232信号 对比
  14. Extended Kalman Filter vs. Error State Kalman Filter for Aircraft Attitude Estimation 翻译
  15. Vue2:使用Vant UI实现网易云评论页上拉和下拉刷新
  16. 大学里,单身率最高的专业竟然是这些!
  17. 优雅高效的多边形对称性判定算法
  18. Tensorflow的基本概念与常用函数
  19. WIN10和MAC OS双系统,调整MAC os分区给WIN10系统扩C盘
  20. Atitit 二维码和条码的历史发展 1.发展历程 编辑提及二维码的诞生,我们还得倒回至上个世纪 60 年代之后的日本,虽然 1945 年的第二次世界大战之中日本沦为战败国,可是在经济方面日本却进入

热门文章

  1. 苏黎世联邦理工学院计算机怎么样,哪位大神知道苏黎世联邦理工学院怎么样?...
  2. 《请给我结果》——姜汝祥
  3. 计算机房验收标准,机房标准工程验收标准和方法.doc
  4. 关于Linux下Docker内网离线安装的一些笔记
  5. 2021年计算机试题,2021年计算机试题及答案-20210515145837.doc-原创力文档
  6. 服务器和普通电脑有什么区别?
  7. 程序员应该访问的最佳网站
  8. 并发编程后记_什么是后记? 它与我的打印机有什么关系?
  9. 范数(机器学习中的使用)
  10. 郑州大学网络空间安全学院复试123