RedisTemplate集成+封装RedisUtil

文章目录

1.项目搭建

1.创建一个redis模块
2.调整pom.xml,使其成为单独的模块
1.sun-common-redis的pom.xml 取消parent
2.sun-common的pom.xml 取消对redis模块的管理
3.sun-frame的pom.xml 增加对redis模块的管理
4.关于只在modules中配置子模块,但是子模块没有配置parent的用处
1. 多模块项目的构建管理

使用标签可以将多个子模块组织在一个顶层的父项目中,从而实现以下几个目标:

a. 单点构建

你可以在父项目的根目录下运行一次mvn install命令,就可以构建和安装所有子模块到本地Maven仓库,而不需要分别进入每个子模块目录单独运行构建命令。这大大简化了多模块项目的构建过程。

b. 构建顺序管理

Maven会根据模块间的依赖关系,自动确定各个模块的构建顺序,确保在构建一个模块之前,先构建它所依赖的模块。这在多模块项目中是非常有用的,可以避免手动管理依赖顺序的麻烦。

2. 统一的版本管理

即使子模块没有指定父项目,使用标签仍然可以帮助你管理各个子模块的版本一致性。你可以在父项目的POM文件中统一指定各个子模块的版本号,然后在每个子模块的POM文件中引用这个版本号。

3. 项目结构的组织和清晰度

将多个子模块组织在一个父项目中,可以使项目结构更加清晰,便于管理。通过标签,你可以一目了然地看到项目中包含哪些子模块,以及它们之间的组织结构。

3.sun-common-redis引入redis依赖
xml 复制代码
    <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

1.pom.xml引入sun-common-redis
xml 复制代码
        <!-- 引入sun-common-redis -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>sun-common-redis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
2.application.yml配置redis(集群模式)
sql 复制代码
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:
  
3.TestController.java测试RedisTemplate
1.代码
java 复制代码
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!";
    }
}
2.访问测试(发现有乱码)
4.重写RedisTemlate
1.引入Jackson的依赖
xml 复制代码
        <!-- 重写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>
2.RedisConfig.java
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.测试

3.封装RedisUtil

1.RedisUtil.java
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;
    }
}
相关推荐
Code apprenticeship2 小时前
怎么利用Redis实现延时队列?
数据库·redis·缓存
百度智能云技术站2 小时前
广告投放系统成本降低 70%+,基于 Redis 容量型数据库 PegaDB 的方案设计和业务实践
数据库·redis·oracle
装不满的克莱因瓶2 小时前
【Redis经典面试题六】Redis的持久化机制是怎样的?
java·数据库·redis·持久化·aof·rdb
黄名富5 小时前
Redis 附加功能(二)— 自动过期、流水线与事务及Lua脚本
java·数据库·redis·lua
G_whang6 小时前
centos7下docker 容器实现redis主从同步
redis·docker·容器
.生产的驴6 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
我叫啥都行9 小时前
计算机基础复习12.22
java·jvm·redis·后端·mysql
阿乾之铭10 小时前
Redis四种模式在Spring Boot框架下的配置
redis
on the way 12312 小时前
Redisson锁简单使用
redis
科马13 小时前
【Redis】缓存
数据库·redis·spring·缓存