RedisTemplate集成+封装RedisUtil过程
1.项目搭建
创建一个redis模块
调整pom.xml,使其成为单独的模块
- sun-common-redis的pom.xml 取消parent
- sun-common的pom.xml 取消对redis模块的管理
- sun-frame的pom.xml 增加对redis模块的管理
关于只在modules中配置子模块,但是子模块没有配置parent的用处
1. 多模块项目的构建管理
使用标签可以将多个子模块组织在一个顶层的父项目中,从而实现以下几个目标:
- a. 单点构建
- 你可以在父项目的根目录下运行一次mvn install命令,就可以构建和安装所有子模块到本地Maven仓库,而不需要分别进入每个子模块目录单独运行构建命令。这大大简化了多模块项目的构建过程。
- b. 构建顺序管理
- Maven会根据模块间的依赖关系,自动确定各个模块的构建顺序,确保在构建一个模块之前,先构建它所依赖的模块。这在多模块项目中是非常有用的,可以避免手动管理依赖顺序的麻烦。
2. 统一的版本管理
即使子模块没有指定父项目,使用标签仍然可以帮助你管理各个子模块的版本一致性。你可以在父项目的POM文件中统一指定各个子模块的版本号,然后在每个子模块的POM文件中引用这个版本号。
3. 项目结构的组织和清晰度
将多个子模块组织在一个父项目中,可以使项目结构更加清晰,便于管理。通过标签,你可以一目了然地看到项目中包含哪些子模块,以及它们之间的组织结构。
sun-common-redis引入redis依赖
<dependencies> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.4.2</version> </dependency> <!-- redis的pool --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.9.0</version> </dependency> </dependencies>
2.sun-user集成RedisTemplate
pom.xml引入sun-common-redis
<!-- 引入sun-common-redis --> <dependency> <groupId>com.sunxiansheng</groupId> <artifactId>sun-common-redis</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
application.yml配置redis(集群模式)
spring: # 配置redis(集群模式) redis: password: # Redis服务器密码 database: 0 # 默认数据库为0号 timeout: 10000ms # 连接超时时间是10000毫秒 lettuce: pool: max-active: 8 # 最大活跃连接数,使用负值表示没有限制,最佳配置为核数*2 max-wait: 10000ms # 最大等待时间,单位为毫秒,使用负值表示没有限制,这里设置为10秒 max-idle: 200 # 最大空闲连接数 min-idle: 5 # 最小空闲连接数 cluster: nodes:
TestController.java测试RedisTemplate
代码
package com.sunxiansheng.user.controller; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; /** * Description: * @Author sun * @Create 2024/7/8 17:55 * @Version 1.0 */ @RestController public class TestController { @Resource private RedisTemplate redisTemplate; @RequestMapping("/testRedis") public String testRedis() { redisTemplate.opsForValue().set("name", "sunxiansheng"); return "Hello World!"; } }
访问测试(发现有乱码)
重写RedisTemlate
引入Jackson的依赖
<!-- 重写RedisTemlate需要的jackson序列化工具 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.8.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.4</version> </dependency>
RedisConfig.java
package com.sunxiansheng.redis.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * Description: RedisConfig配置类 * @Author sun * @Create 2024/7/19 11:11 * @Version 1.0 */ @Configuration public class RedisConfig { /** * 重写RedisTemplate 解决乱码问题 * * @param redisConnectionFactory * @return */ @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // key就使用redis提供的序列化RedisSerializer即可 RedisSerializer<String> redisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(redisSerializer); redisTemplate.setHashKeySerializer(redisSerializer); // value要使用Jackson的序列化 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer()); return redisTemplate; } /** * 获取一个Jackson的序列化对象逻辑 * * @return */ private Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer() { // 创建一个Jackson2JsonRedisSerializer对象,用于序列化和反序列化Java对象 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); // 创建一个ObjectMapper对象,用于JSON序列化和反序列化的配置 ObjectMapper objectMapper = new ObjectMapper(); // 设置ObjectMapper的可见性,使其可以访问所有属性 objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 配置ObjectMapper,使其在遇到未知属性时不会抛出异常 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 将配置好的ObjectMapper设置到Jackson2JsonRedisSerializer中 jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 返回配置好的Jackson2JsonRedisSerializer对象 return jackson2JsonRedisSerializer; } }
测试
3.封装RedisUtil
RedisUtil.java
package com.sunxiansheng.redis.util; import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import java.util.stream.Stream; /** * Description: RedisUtil工具类 * @Author sun * @Create 2024/6/5 14:17 * @Version 1.0 */ @Component public class RedisUtil { @Resource private RedisTemplate redisTemplate; private static final String CACHE_KEY_SEPARATOR = "."; /** * 构建缓存key * @param strObjs 多个字符串拼接成缓存key * @return 拼接后的缓存key */ public String buildKey(String... strObjs) { return Stream.of(strObjs).collect(Collectors.joining(CACHE_KEY_SEPARATOR)); } /** * 是否存在key * @param key Redis中的key * @return true如果key存在,否则false */ public boolean exist(String key) { return redisTemplate.hasKey(key); } /** * 删除key * @param key Redis中的key * @return true如果删除成功,否则false */ public boolean del(String key) { return redisTemplate.delete(key); } /** * 设置key-value对 * @param key Redis中的key * @param value 要设置的值 */ public void set(String key, String value) { redisTemplate.opsForValue().set(key, value); } /** * 设置key-value对,如果key不存在,则设置成功,并指定过期时间 * @param key Redis中的key * @param value 要设置的值 * @param time 过期时间 * @param timeUnit 时间单位 * @return true如果设置成功,否则false */ public boolean setNx(String key, String value, Long time, TimeUnit timeUnit) { return redisTemplate.opsForValue().setIfAbsent(key, value, time, timeUnit); } /** * 获取指定key的值 * @param key Redis中的key * @return key对应的值 */ public String get(String key) { return (String) redisTemplate.opsForValue().get(key); } /** * 向有序集合中添加元素 * @param key Redis中的key * @param value 元素的值 * @param score 元素的分数 * @return true如果添加成功,否则false */ public Boolean zAdd(String key, String value, Long score) { return redisTemplate.opsForZSet().add(key, value, Double.valueOf(String.valueOf(score))); } /** * 获取有序集合的元素数量 * @param key Redis中的key * @return 元素数量 */ public Long countZset(String key) { return redisTemplate.opsForZSet().size(key); } /** * 获取有序集合指定范围内的元素 * @param key Redis中的key * @param start 起始位置 * @param end 结束位置 * @return 指定范围内的元素集合 */ public Set<String> rangeZset(String key, long start, long end) { return redisTemplate.opsForZSet().range(key, start, end); } /** * 删除有序集合中的指定元素 * @param key Redis中的key * @param value 要删除的元素 * @return 被删除的元素数量 */ public Long removeZset(String key, Object value) { return redisTemplate.opsForZSet().remove(key, value); } /** * 删除有序集合中的多个元素 * @param key Redis中的key * @param value 要删除的元素集合 */ public void removeZsetList(String key, Set<String> value) { value.forEach(val -> redisTemplate.opsForZSet().remove(key, val)); } /** * 获取有序集合中指定元素的分数 * @param key Redis中的key * @param value 元素的值 * @return 元素的分数 */ public Double score(String key, Object value) { return redisTemplate.opsForZSet().score(key, value); } /** * 获取有序集合中指定分数范围内的元素 * @param key Redis中的key * @param start 起始分数 * @param end 结束分数 * @return 指定分数范围内的元素集合 */ public Set<String> rangeByScore(String key, long start, long end) { return redisTemplate.opsForZSet().rangeByScore(key, Double.valueOf(String.valueOf(start)), Double.valueOf(String.valueOf(end))); } /** * 增加有序集合中指定元素的分数 * @param key Redis中的key * @param obj 元素的值 * @param score 增加的分数 * @return 增加后的分数 */ public Object addScore(String key, Object obj, double score) { return redisTemplate.opsForZSet().incrementScore(key, obj, score); } /** * 获取有序集合中指定元素的排名 * @param key Redis中的key * @param obj 元素的值 * @return 元素的排名 */ public Object rank(String key, Object obj) { return redisTemplate.opsForZSet().rank(key, obj); } /** * 从 Redis 有序集合(Sorted Set)中按分数范围获取成员及其分数 * @param key 排行榜的key * @param start 起始位置(包含) * @param end 结束位置(包含) * @return Set<ZSetOperations.TypedTuple<String>> : 每个 TypedTuple 对象包含以下内容:value: 集合中的成员,score: 成员的分数。 */ public Set<ZSetOperations.TypedTuple<String>> rankWithScore(String key, long start, long end) { return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end); } /** * 向Redis中的hash结构存储数据 * @param key 一个hash结构的key * @param hashKey hash中的小key * @param hashVal hash中的小value */ public void putHash(String key, String hashKey, Object hashVal) { redisTemplate.opsForHash().put(key, hashKey, hashVal); } /** * Redis中的String类型,获取value时将其转换为int类型 * @param key Redis中的key * @return key对应的整数值 */ public Integer getInt(String key) { return (Integer) redisTemplate.opsForValue().get(key); } /** * Redis中的String类型,将value增加一 * @param key Redis中的key * @param count 增加的数量 */ public void increment(String key, Integer count) { redisTemplate.opsForValue().increment(key, count); } /** * Redis中的hash类型,根据key来将每一个hashKey和hashValue转换为Map类型 * @param key Redis中的hash结构的key * @return Map<Object, Object> 包含hash结构中的所有键值对 */ public Map<Object, Object> getHashAndDelete(String key) { Map<Object, Object> map = new HashMap<>(); // 扫描hash,指定每一个Entry的类型,这里返回的就是Map的游标,可以进行遍历 Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, ScanOptions.NONE); // 遍历每一条数据,放到map中 while (cursor.hasNext()) { Map.Entry<Object, Object> next = cursor.next(); Object hashKey = next.getKey(); Object hashValue = next.getValue(); map.put(hashKey, hashValue); // 每遍历一条就删除 redisTemplate.opsForHash().delete(key, hashKey); } return map; } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Redisson分布式限流器RRateLimiter的使用及原理小结
本文主要介绍了Redisson分布式限流器RRateLimiter的使用及原理小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2024-06-06关于使用IDEA的springboot框架往Redis里写入数据乱码问题
这篇文章主要介绍了用IDEA的springboot框架往Redis里写入数据乱码问题,本文给大家分享解决方法通过图文示例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-10-10
最新评论