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

Redis工具类

文章目录

  • Redis的自动配置
  • Redis配置类
    • 问题 一
    • 问题二
  • Redis工具类

Redis的自动配置

在这里插入图片描述

通过源码可以看出,SpringBoot自动帮我们在容器中生成了一个RedisTemplate和一个StringRedisTemplate。

​ 看到这个**@ConditionalOnMissingBean注解后,就知道如果Spring容器中有了RedisTemplate对象了,这个自动配置的RedisTemplate不会实例化**。因此我们可以直接自己写个配置类,配置RedisTemplate。

该注解核心作用是:当容器中不存在指定类型(或名称)的 Bean 时,才会创建当前注解标注的 Bean

Redis配置类

代码如下:

@Configuration
public class RedisConfig {@Bean@SuppressWarnings(value = { "unchecked", "rawtypes" })public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory){RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);// 使用StringRedisSerializer来序列化和反序列化redis的key值template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(serializer);// Hash的key也采用StringRedisSerializer的序列化方式template.setHashKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(serializer);template.afterPropertiesSet();return template;}
}

问题 一

@SuppressWarnings(value = { "unchecked", "rawtypes" })的作用

这个注解用于抑制编译器产生的未检查类型转换警告unchecked)和原始类型使用警告rawtypes)。

  1. unchecked 警告

当代码中存在没有进行类型检查的泛型转换时,编译器会提示警告。例如:

List<String> list = (List<String>) redisTemplate.opsForValue().get("key");

这里的强制类型转换没有进行运行时检查,可能在运行时抛出ClassCastException。添加@SuppressWarnings("unchecked")可以消除这个警告。

  1. rawtypes 警告

当使用泛型类但没有指定具体类型参数时,编译器会提示原始类型警告。

RedisTemplate template = new RedisTemplate(); // 未指定泛型参数

问题二

此配置类作用?

为什么需要配置序列化器?

  1. 序列化方式不符合预期,出现乱码或不可读数据

RedisTemplate 默认的序列化器如下:

  • key 和 value 的默认序列化器JdkSerializationRedisSerializer(基于 JDK 自带的序列化)
  • Hash 结构的 key 和 value 默认序列化器:同样是JdkSerializationRedisSerializer

这种默认序列化会导致:

  • 存储到 Redis 中的 key 和 value 会带有额外的类信息(如\xAC\xED\x00\x05t\x00\x06test),在 Redis 客户端(如 Redis Desktop Manager)中查看时是乱码,无法直观阅读。
  • 反序列化时依赖类的全路径名,如果类名或包名修改,会导致反序列化失败(报ClassNotFoundException)。
  1. 自定义对象存储失败

如果直接使用未配置的 RedisTemplate 存储自定义实体类对象,会因为默认序列化器的限制:

  • 要求对象必须实现Serializable接口,否则抛出序列化异常。
  • 即使实现了Serializable,也会如上述问题一样,存储的数据可读性差,且耦合性高(依赖类结构)

配置前:

在这里插入图片描述

配置后:

在这里插入图片描述

  1. key 和 hashKey 用 StringRedisSerializer 的必要性
    • Redis 的 key 通常是字符串(如 user:100order:200),StringRedisSerializer 能确保 key 以可读的字符串形式存储,避免序列化后出现乱码(如 JDK 序列化会导致 key 带类名前缀)。
    • hashKey 是 Redis Hash 结构中的字段名,同样需要可读性,因此也采用 StringRedisSerializer
  2. value 和 hashValue 用 FastJsonRedisSerializer 的合理性
    • 示例选择 FastJson 作为 value 序列化器,是因为 JSON 格式具有 可读性强、体积小 的优点,且 FastJson 性能较高。
    • 对于 Java 对象(如实体类、集合),JSON 序列化能兼容大多数场景,避免 JDK 序列化的缺点(如必须实现 Serializable 接口、数据不可读)。
  3. 无需配置其他序列化器的原因
    • RedisTemplate 的序列化器配置遵循 “全局默认” 原则:一旦通过 setKeySerializersetValueSerializer 等方法设置了序列化器,所有通过该 RedisTemplate 操作 Redis 的请求都会使用这些序列化器。
    • 示例场景中,StringRedisSerializer(key)+ FastJsonRedisSerializer(value)已覆盖绝大多数常见需求(字符串 key + JSON 对象 value),因此无需额外配置其他序列化器。

Redis工具类

这里的工具类并不是完整的,但学习够用了。

package com.luxiya.utils;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;import java.util.*;
import java.util.concurrent.TimeUnit;@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache
{@Autowiredpublic RedisTemplate redisTemplate;/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值*/public <T> void setCacheObject(final String key, final T value){redisTemplate.opsForValue().set(key, value);}/*** 缓存基本的对象,Integer、String、实体类等** @param key 缓存的键值* @param value 缓存的值* @param timeout 时间* @param timeUnit 时间颗粒度*/public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit){redisTemplate.opsForValue().set(key, value, timeout, timeUnit);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout){return expire(key, timeout, TimeUnit.SECONDS);}/*** 设置有效时间** @param key Redis键* @param timeout 超时时间* @param unit 时间单位* @return true=设置成功;false=设置失败*/public boolean expire(final String key, final long timeout, final TimeUnit unit){return redisTemplate.expire(key, timeout, unit);}/*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public <T> T getCacheObject(final String key){ValueOperations<String, T> operation = redisTemplate.opsForValue();return operation.get(key);}/*** 删除单个对象** @param key*/public boolean deleteObject(final String key){return redisTemplate.delete(key);}/*** 删除集合对象** @param collection 多个对象* @return*/public long deleteObject(final Collection collection){return redisTemplate.delete(collection);}/*** 缓存List数据** @param key 缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public <T> long setCacheList(final String key, final List<T> dataList){Long count = redisTemplate.opsForList().rightPushAll(key, dataList);return count == null ? 0 : count;}/*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public <T> List<T> getCacheList(final String key){return redisTemplate.opsForList().range(key, 0, -1);}/*** 缓存Set** @param key 缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet){BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);Iterator<T> it = dataSet.iterator();while (it.hasNext()){setOperation.add(it.next());}return setOperation;}/*** 获得缓存的set** @param key* @return*/public <T> Set<T> getCacheSet(final String key){return redisTemplate.opsForSet().members(key);}/*** 缓存Map** @param key* @param dataMap*/public <T> void setCacheMap(final String key, final Map<String, T> dataMap){if (dataMap != null) {redisTemplate.opsForHash().putAll(key, dataMap);}}/*** 获得缓存的Map** @param key* @return*/public <T> Map<String, T> getCacheMap(final String key){return redisTemplate.opsForHash().entries(key);}/*** 往Hash中存入数据** @param key Redis键* @param hKey Hash键* @param value 值*/public <T> void setCacheMapValue(final String key, final String hKey, final T value){redisTemplate.opsForHash().put(key, hKey, value);}/*** 获取Hash中的数据** @param key Redis键* @param hKey Hash键* @return Hash中的对象*/public <T> T getCacheMapValue(final String key, final String hKey){HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();return opsForHash.get(key, hKey);}/*** 删除Hash中的数据** @param key* @param hkey*/public void delCacheMapValue(final String key, final String hkey){HashOperations hashOperations = redisTemplate.opsForHash();hashOperations.delete(key, hkey);}/*** 获取多个Hash中的数据** @param key Redis键* @param hKeys Hash键集合* @return Hash对象集合*/public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys){return redisTemplate.opsForHash().multiGet(key, hKeys);}/*** 获得缓存的基本对象列表** @param pattern 字符串前缀* @return 对象列表*/public Collection<String> keys(final String pattern){return redisTemplate.keys(pattern);}
}
http://www.lryc.cn/news/592590.html

相关文章:

  • RHCE第二次作业
  • MyBatis:配置文件完成增删改查_添加
  • Java 核心工具类 API 详解(一):从 Math 到 Runtime 的实用指南
  • 谷歌浏览器Chrome的多用户配置文件功能
  • 简单易懂,基本地址变换机构
  • 高防IP能够防御CC攻击吗?它具备哪些显著优势?
  • 【easytokenizer】高性能文本 Tokenizer库 | 源码详解与编译安装
  • Java中类加载器及双亲委派机制原理
  • 2023 年 3 月青少年软编等考 C 语言八级真题解析
  • Windows8.1安装哪个版本的vscode?
  • 基于华为openEuler系统安装DailyNotes个人笔记管理工具
  • HTML常见标签
  • 关于Mysql开启慢查询日志报错:13 - Permission denied的解决方案
  • 爬虫小知识(二)网页进行交互
  • 前端流式渲染流式SSR详解
  • 模板初阶和C++内存管理
  • 【软件重构】如何避免意外冗余
  • 高速公路自动化安全监测主要内容
  • A33-vstar报错记录:ERROR: build kernel Failed
  • 深入理解Linux文件I/O:系统调用与标志位应用
  • 广东省省考备考(第四十九天7.18)——判断推理:位置规律(听课后强化训练)
  • *SFT深度实践指南:从数据构建到模型部署的全流程解析
  • Linux | Bash 子字符串提取
  • Redis原理之哨兵机制(Sentinel)
  • Android性能优化之网络优化
  • 【锂电池剩余寿命预测】TCN时间卷积神经网络锂电池剩余寿命预测(Pytorch完整源码和数据)
  • 如何用Python并发下载?深入解析concurrent.futures 与期物机制
  • 安卓Android项目 报错:系统找不到指定文件
  • python学智能算法(二十四)|SVM-最优化几何距离的理解
  • 【52】MFC入门到精通——MFC串口助手(二)---通信版(发送数据 、发送文件、数据转换、清空发送区、打开/关闭文件),附源码