开发者

RedisTemplate集成+封装RedisUtil过程

目录
  • 1.项目搭建
    • 创建一个Redis模块
    • 调整pom.XML,使其成为单独的模块
    • sun-common-redis引入redis依赖
  • 2.sun-user集成RedisTemplate
    • 3.封装RedisUtil
      • 总结

        1.项目搭建

        创建一个redis模块

        RedisTemplate集成+封装RedisUtil过程

        调整pom.xml,使其成为单独的模块

        • sun-common-redis的pom.xml 取消parent

        RedisTemplate集成+封装RedisUtil过程

        • sun-common的pom.xml 取消对redis模块的管理

        RedisTemplate集成+封装RedisUtil过程

        • sun-frame的pom.xml 增加对redis模块的管理

        RedisTemplate集成+封装RedisUtil过程

        关于只在modules中配置子模块,但是子模块没有配置parent的用处

        1. 多模块项目的构建管理

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

        • a. 单点构建
        • 你可以在父项目的根目录下运行一次mvn install命令,就可以构建和安装所有子模块到本地Maven仓库,而不需要分别进入每个子模块目录单独运行构建命令。这大大简化了多模块项目的构建过程。
        • b. 构建顺序管理
        • Maven会根据模块间的依赖关系,自动确定各个模块的构建顺序,确保在构建一个模块之前,先构建它所依赖的模块。这在多模块项目中是非常有用的,可以避免手动管理依赖顺序的麻烦。

        2. 统一的版本管理

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

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

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

        sun-common-redis引入redis依赖

            <dependencies>
                <!-- redis -->
                <dependency>
                    <groupId>org.springfandroidramework.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!";
            }
        }

        访问测试(发现有乱码)

        RedisTemplate集成+封装RedisUtil过程

        重写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>

        RedisTemplate集成+封装RedisUtil过程

        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);
                // vpythonalue要使用Jackson的序列化
                redisTemplate.setValueSerializer(jackson2JsonRedisSerializer());
                redisTemoGTKpKXZmBplate.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;
            }
        
        }

        RedisTemplate集成+封装RedisUtil过程

        测试

        RedisTemplate集成+封装RedisUtil过程

        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
             * @p编程客栈aram 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;
            }
        }

        总结

        以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新数据库

        数据库排行榜