一次springboot和redis缓存的实践

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 性能缓慢是开发人员经常面临的一个反复出现且复杂的问题。解决此类问题的最常见方法之一是通过缓存。实际上,这种机制允许在任何类型的应用程序的性能方面实现显着改进。问题是处理缓存并不是一件容易的事。幸运的是,Spring Boot 透明地提供了缓存,这要归功于 Spring Boot 缓存抽象,这是一种允许一致使用各种缓存方法而对代码影响最小的机制。让我们看看开始处理它应该知道的一切。

性能缓慢是开发人员经常面临的一个反复出现且复杂的问题。解决此类问题的最常见方法之一是通过缓存。实际上,这种机制允许在任何类型的应用程序的性能方面实现显着改进。问题是处理缓存并不是一件容易的事。幸运的是,Spring Boot 透明地提供了缓存,这要归功于 Spring Boot 缓存抽象,这是一种允许一致使用各种缓存方法而对代码影响最小的机制。让我们看看开始处理它应该知道的一切。

首先,我们将介绍缓存的概念。然后,我们将研究最常见的 Spring Boot 缓存相关注解,了解最重要的注解是什么,在哪里以及如何使用它们。接下来,是时候看看在撰写本文时 Spring Boot 支持的最流行的缓存引擎有哪些。最后,我们将通过一个示例了解 Spring Boot 缓存的实际应用。

什么是缓存

缓存是一种旨在提高任何类型应用程序性能的机制。它依赖于缓存,缓存可以看作是一种临时的快速访问软件或硬件组件,用于存储数据以减少处理与相同数据相关的未来请求所需的时间。处理缓存是很复杂的,但掌握这个概念对于任何开发人员来说几乎都是不可避免的。如果您有兴趣深入研究缓存、了解它是什么、它是如何工作的以及它最重要的类型是什么,您应该首先点击这个链接。

如何在 Spring Boot 应用程序中实现 Redis 缓存?

为了使用 Spring Boot 实现 Redis 缓存,我们需要创建一个小型应用程序,该应用程序将具有 CRUD 操作。然后我们将在检索、更新和删除操作中应用 Redis 缓存功能。

我们将使用 REST 创建一个 CRUD 应用程序。在这里,假设我们的实体类是 Invoice.java。为了创建一个完整的 REST 应用程序,我们将根据行业最佳实践拥有控制器、服务和存储库层。一旦我们完成了 Invoice REST Application 的开发,我们将进一步在某些方法上应用注解来获得 Redis Cache 的好处。这是在我们的应用程序中实现 Redis 缓存的分步方法。

需要引入的依赖
<dependency> 
 <groupId>org.springframework.boot</groupId> 
 <artifactId>spring-boot-starter-data-redis</artifactId> 
 </dependency> 
复制代码
配置文件
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/rediscachetest
spring.datasource.username=root
spring.datasource.password=****
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.cache.type=redis
spring.cache.redis.cache-null-values=true
#spring.cache.redis.time-to-live=40000
复制代码

启动类注解  @EnableCaching at starter class

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
 @SpringBootApplication
 @EnableCaching
public class RedisAsaCacheWithSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(RedisAsaCacheWithSpringBootApplication.class, args);
}
} 
复制代码
创建 Invoice.java实体类
@Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Entity
public class Invoice implements Serializable{
private static final long serialVersionUID = -4439114469417994311L;
 @Id
 @GeneratedValue
private Integer invId;
private String invName;
private Double invAmount;
} 
复制代码

创建一个接口 InvoiceRepository.java

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.dev.springboot.redis.model.Invoice;
 @Repository
public interface InvoiceRepository extends JpaRepository<Invoice, Integer> {
} 
复制代码

自定义异常类

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class InvoiceNotFoundException extends RuntimeException {
private static final long serialVersionUID = 7428051251365675318L;
public InvoiceNotFoundException(String message) {
super(message);
}
} 
复制代码

一个具体的实现类,中间包含一些增删改查的方法

import com.dev.springboot.redis.model.Invoice;
import java.util.List;
public interface InvoiceService {
public Invoice saveInvoice(Invoice inv);
public Invoice updateInvoice(Invoice inv, Integer invId);
public void deleteInvoice(Integer invId);
public Invoice getOneInvoice(Integer invId);
public List<Invoice> getAllInvoices();
} 
复制代码
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.dev.springboot.redis.exception.InvoiceNotFoundException;
import com.dev.springboot.redis.model.Invoice;
import com.dev.springboot.redis.repo.InvoiceRepository;
 @Service
public class InvoiceServiceImpl implements InvoiceService {
 @Autowired
private InvoiceRepository invoiceRepo;
 @Override
public Invoice saveInvoice(Invoice inv) {
return invoiceRepo.save(inv);
}
 @Override
@CachePut(value="Invoice", key="#invId")
public Invoice updateInvoice(Invoice inv, Integer invId) {
Invoice invoice = invoiceRepo.findById(invId)
.orElseThrow(() -> new InvoiceNotFoundException("Invoice Not Found"));
invoice.setInvAmount(inv.getInvAmount());
invoice.setInvName(inv.getInvName());
return invoiceRepo.save(invoice);
}
 @Override
@CacheEvict(value="Invoice", key="#invId")
// @CacheEvict(value="Invoice", allEntries=true) //in case there are multiple records to delete
public void deleteInvoice(Integer invId) {
Invoice invoice = invoiceRepo.findById(invId)
.orElseThrow(() -> new InvoiceNotFoundException("Invoice Not Found"));
invoiceRepo.delete(invoice);
}
 @Override
@Cacheable(value="Invoice", key="#invId")
public Invoice getOneInvoice(Integer invId) {
Invoice invoice = invoiceRepo.findById(invId)
.orElseThrow(() -> new InvoiceNotFoundException("Invoice Not Found"));
return invoice;
}
 @Override
@Cacheable(value="Invoice")
public List<Invoice> getAllInvoices() {
return invoiceRepo.findAll();
}
} 
复制代码

添加Controller接口,进行请求测试

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.dev.springboot.redis.model.Invoice;
import com.dev.springboot.redis.service.InvoiceService;
 @RestController
@RequestMapping("/invoice")
public class InvoiceController {
 @Autowired
InvoiceService invoiceService;
@PostMapping("/saveInv")
public Invoice saveInvoice(@RequestBody Invoice inv) {
return invoiceService.saveInvoice(inv);
}
@GetMapping("/allInv")
public ResponseEntity<List<Invoice>> getAllInvoices(){
return ResponseEntity.ok(invoiceService.getAllInvoices());
}
@GetMapping("/getOne/{id}")
public Invoice getOneInvoice(@PathVariable Integer id) {
return invoiceService.getOneInvoice(id);
}
@PutMapping("/modify/{id}")
public Invoice updateInvoice(@RequestBody Invoice inv, @PathVariable Integer id) {
return invoiceService.updateInvoice(inv, id);
}
@DeleteMapping("/delete/{id}")
public String deleteInvoice(@PathVariable Integer id) {
invoiceService.deleteInvoice(id);
return "Employee with id: "+id+ " Deleted !";
}
}


作者:饱饱巴士

链接:https://juejin.cn/post/7164317075693895716

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
缓存 NoSQL Java
什么是缓存?如何在 Spring Boot 中使用缓存框架
什么是缓存?如何在 Spring Boot 中使用缓存框架
71 0
|
20天前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
164 85
|
17天前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文详细探讨了分布式系统和缓存应用中的经典问题——缓存穿透。缓存穿透是指用户请求的数据在缓存和数据库中都不存在,导致大量请求直接落到数据库上,可能引发数据库崩溃或性能下降。文章介绍了几种有效的解决方案,包括接口层增加校验、缓存空值、使用布隆过滤器、优化数据库查询以及加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统的影响,提升系统的稳定性和性能。
|
2月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
2月前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
2月前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
76 8
|
1月前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
148 5
|
1月前
|
缓存 NoSQL Java
Spring Boot中的分布式缓存方案
Spring Boot提供了简便的方式来集成和使用分布式缓存。通过Redis和Memcached等缓存方案,可以显著提升应用的性能和扩展性。合理配置和优化缓存策略,可以有效避免常见的缓存问题,保证系统的稳定性和高效运行。
51 3
|
2月前
|
安全 Java 数据安全/隐私保护
如何使用Spring Boot进行表单登录身份验证:从基础到实践
如何使用Spring Boot进行表单登录身份验证:从基础到实践
65 5
|
2月前
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
57 5