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;
    }
}
相关推荐
Kagol6 小时前
macOS 和 Windows 操作系统下如何安装和启动 MySQL / Redis 数据库
redis·后端·mysql
hzulwy7 小时前
Redis常用的数据结构及其使用场景
数据库·redis
ashane13148 小时前
Redis 哨兵集群(Sentinel)与 Cluster 集群对比
redis
Y第五个季节9 小时前
Redis - HyperLogLog
数据库·redis·缓存
Justice link10 小时前
企业级NoSql数据库Redis集群
数据库·redis·缓存
爱的叹息13 小时前
Spring Boot 集成Redis 的Lua脚本详解
spring boot·redis·lua
morris13121 小时前
【redis】redis实现分布式锁
数据库·redis·缓存·分布式锁
爱的叹息1 天前
spring boot集成reids的 RedisTemplate 序列化器详细对比(官方及非官方)
redis
weitinting1 天前
Ali linux 通过yum安装redis
linux·redis
纪元A梦1 天前
Redis最佳实践——首页推荐与商品列表缓存详解
数据库·redis·缓存