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

Springboot——Redis的使用

在当今的软件开发领域,缓存技术是提升应用性能的关键手段之一。Redis 作为一款高性能的键值对存储数据库,凭借其出色的读写速度和丰富的数据结构,在缓存场景中得到了广泛应用。Spring Boot 作为一款简化 Spring 应用开发的框架,与 Redis 的集成可以让开发者轻松地在项目中使用 Redis 缓存。本文将详细介绍如何在 Spring Boot 项目中集成和使用 Redis。

项目搭建

首先在你的项目中引入redis的Maven依赖确保使用

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

在 application.properties 或 application.yml 中配置 Redis 连接信息。以下是 application.yml 的示例配置:

spring: redis:database: 0           # Redis服务器数据库host: 127.0.0.1       # Redis服务器地址port: 6379            # Redis服务器连接端口password: 123456      # Redis服务器连接密码(默认为空)timeout: 6000         # Redis连接超时时间(毫秒)

Redis 基本操作

配置Redis的配置类

package com.lppaa.redisdemo.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;
import java.util.HashMap;
import java.util.Map;@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {@Beanpublic CacheManager cacheManager(RedisConnectionFactory factory){RedisSerializer<String> keyRedisSerializer = new StringRedisSerializer(); // redis的key序列化方式Jackson2JsonRedisSerializer valueRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // redis的value的序列化//解决查询缓存转换异常的问题ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);valueRedisSerializer.setObjectMapper(om);//配置序列化(解决乱码的问题)RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ZERO) // 默认生存时间.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keyRedisSerializer)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueRedisSerializer)).disableCachingNullValues();//缓存配置mapMap<String,RedisCacheConfiguration> cacheConfigurationMap=new HashMap<>();//自定义缓存名,后面使用的@Cacheable的CacheNamecacheConfigurationMap.put("myRedis",config);
//        cacheConfigurationMap.put("default",config);RedisCacheManager cacheManager = RedisCacheManager.builder(factory).cacheDefaults(config).withInitialCacheConfigurations(cacheConfigurationMap).build();return cacheManager;}@Beanpublic RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {StringRedisTemplate template = new StringRedisTemplate(factory);Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);template.setValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}}
  • CacheManager方法:负责管理缓存的创建、获取和清理等操作。此方法对 Redis 缓存管理器进行了配置,具体步骤如下:
    • 序列化配置
      • 对 Redis 的键使用 StringRedisSerializer 进行序列化。
      • 对 Redis 的值使用 Jackson2JsonRedisSerializer 进行序列化,同时配置 ObjectMapper 以避免查询缓存时出现转换异常。
    • 缓存配置
      • 借助 RedisCacheConfiguration 配置默认的缓存策略,包含默认生存时间、键和值的序列化方式,并且禁止缓存空值。
      • 创建一个 Map 来存放自定义的缓存配置,这里定义了一个名为 "myRedis" 的缓存。
    • 缓存管理器构建
      • 利用 RedisCacheManager.builder 构建缓存管理器,设置默认缓存配置以及自定义的缓存配置。
  • redisTemplate方法:作用是在代码里对 Redis 进行操作

    • 采用 StringRedisTemplate 作为基础模板,它是 RedisTemplate 的子类,专门用于处理字符串类型的键和值。
    • 同样使用 Jackson2JsonRedisSerializer 对值进行序列化,并且配置 ObjectMapper 以防止查询缓存时出现转换异常。

编写服务层逻辑

EmployeeService接口类
public interface EmployeeService {List<Employee> findAll();Employee findById(Integer id);Employee update(Employee employee);Integer delete(Integer id);}

EmployeeServiceImpl接口实现类

package com.lppaa.redisdemo.service.serviceImpl;import com.lppaa.redisdemo.dao.EmployeeDao;
import com.lppaa.redisdemo.entity.Employee;
import com.lppaa.redisdemo.service.EmployeeService;
import io.swagger.models.auth.In;
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 java.util.Collections;
import java.util.Date;
import java.util.List;@Service
public class EmployeeServiceImpl implements EmployeeService {@AutowiredEmployeeDao employeeDao;@Overridepublic List<Employee> findAll() {return employeeDao.findAll();}@Override@Cacheable(cacheNames = "myRedis" ,key = "T(com.lppaa.redisdemo.utils.MD5Utils).md5('EmployeeService_findById' + #id)" ,unless = "#result==null")public Employee findById(Integer id) {System.out.println("进入方法,去数据库查询");return employeeDao.findById(id);}@Override@CachePut(cacheNames = "myRedis", key = "T(com.lppaa.redisdemo.utils.MD5Utils).md5('EmployeeService_findById' + #employee.id)",condition = "#result != null")public Employee update(Employee employee) {employee.setTime(new Date());Integer ans = employeeDao.update(employee);if(ans>0)return employeeDao.findById(employee.getId());return null;//表示更新失败 结果为空 不存入缓存 结果不变}@Override@CacheEvict(cacheNames = "myRedis", key = "T(com.lppaa.redisdemo.utils.MD5Utils).md5('EmployeeService_findById' + #id)")public Integer delete(Integer id) {Integer s = employeeDao.delete(id);return s;}
}
@Cacheable 注解 
  • @Cacheable 注解:用于标记该方法的结果可以被缓存。
    • cacheNames = "myRedis":指定使用名为 myRedis 的缓存,这个缓存名称在 RedisConfig 类中配置。
    • key = "T(com.lppaa.redisdemo.utils.MD5Utils).md5('EmployeeService_findById' + #id)":使用 SpEL(Spring Expression Language)表达式生成缓存的键。这里调用 MD5Utils 类的 md5 方法对 "EmployeeService_findById" 和传入的 id 拼接后的字符串进行 MD5 加密,确保每个不同的 id 对应一个唯一的缓存键。
    • unless = "#result==null":表示如果方法的返回结果为 null,则不将结果存入缓存。
  • 当调用该方法时,Spring 会先检查缓存中是否存在对应的键,如果存在则直接返回缓存中的结果,否则执行方法体中的代码,从数据库中查询数据,并将结果存入缓存。
@CachePut 注解
  • @CachePut 注解:用于更新缓存。无论缓存中是否存在对应的键,都会执行方法体中的代码,并将方法的返回结果存入缓存。
    • cacheNames = "myRedis":指定使用名为 myRedis 的缓存。
    • key = "T(com.lppaa.redisdemo.utils.MD5Utils).md5('EmployeeService_findById' + #employee.id)":生成缓存的键,与 findById 方法使用相同的键生成策略。
    • condition = "#result != null":表示只有当方法的返回结果不为 null 时,才将结果存入缓存。
  • 该方法首先更新员工的时间戳,然后调用 EmployeeDao 的 update 方法更新数据库中的员工信息。如果更新成功,则再次查询数据库获取最新的员工信息并返回,同时更新缓存;如果更新失败,则返回 null,不更新缓存。
CacheEvict 注解
  • @CacheEvict 注解:用于从缓存中移除指定键的缓存项。
    • cacheNames = "myRedis":指定使用名为 myRedis 的缓存。
    • key = "T(com.lppaa.redisdemo.utils.MD5Utils).md5('EmployeeService_findById' + #id)":生成要移除的缓存键,与 findById 和 update 方法使用相同的键生成策略。
  • 该方法调用 EmployeeDao 的 delete 方法从数据库中删除指定 id 的员工信息,并从缓存中移除对应的缓存项。

编写控制层逻辑

package com.lppaa.redisdemo.controller;import com.alibaba.fastjson.JSON;
import com.lppaa.redisdemo.entity.Employee;
import com.lppaa.redisdemo.entity.User;
import com.lppaa.redisdemo.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import java.util.Date;@RestController
@RequestMapping("/test")
public class RedisController {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate EmployeeService employeeService;@Autowiredprivate StringRedisTemplate stringRedisTemplate;@RequestMapping("/aaa")public String testA(){User user = new User();user.setName("李四");user.setAge(20);
//        redisTemplate.opsForValue().set("user", JSON.toJSONString(user));//redisTemplate.opsForValue().set("ttt", user);stringRedisTemplate.opsForValue().set("qweirj", JSON.toJSONString(user));return "success";}@RequestMapping("/findbyid")@ResponseBodypublic Employee findbyId(Integer id){Employee employee = employeeService.findById(id);return employee;}@RequestMapping("/update")@ResponseBodypublic String update(Employee e){e.setTime(new Date());Employee byId = employeeService.update(e);if(byId != null)return "success";return "false";}@RequestMapping("/delete")@ResponseBodypublic String dete(Integer id){Integer s = employeeService.delete(id);if(s == 1)return "success";return "false";}
}

最后打开Redis即可进行使用。

相关文章:

  • .NET 6 + Dapper + User-Defined Table Type
  • ElasticSearch深入解析(三):Elasticsearch 7的安装与配置、Kibana安装
  • Kafka 核心使用机制总结
  • ADW600防护等级与电气安全设计要点详解
  • MCU开发学习记录11 - ADC学习与实践(HAL库) - 单通道ADC采集、多通道ADC采集、定时器触发连续ADC采集 - STM32CubeMX
  • 从零到精通:探索GoFrame框架中gcron的定时任务之道 —— 优势、实践与踩坑经验
  • Java的JUC详细全解
  • Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
  • 深度探究获取淘宝商品数据的途径|API接口|批量自动化采集商品数据
  • 小学数学出题器:自动化作业生成
  • 智能指针(weak_ptr )之三
  • equals与hashCode的关系探究
  • 一 、环境的安装 Anaconda + Pycharm + PaddlePaddle
  • 火山云生态的体现
  • 容器内部无法访问宿主机服务的原因及解决方法
  • 深入解析:RocketMQ、RabbitMQ和Kafka的区别与使用场景
  • MySQL的日志--Redo Log【学习笔记】
  • opencv--图像
  • Synternet数据流正式上线Google Cloud Web3
  • Vue3 模板语法
  • 更好发挥汽车产业在扩投资促消费方面的带动作用!陈吉宁调研上海车展
  • 兰斯莫斯想在雅典卫城拍《拯救地球》,希腊当局:价值观不符
  • 明日出征!航天员详细信息来啦
  • 青岛:今年计划新增城镇住房约5.77万套,推动房地产市场回稳
  • 透纳仍是英国最好的艺术家,浦东美术馆有他的画展
  • 广西大部气象干旱已达特旱