SpringBoot集成Redis

06-13 1610阅读

Redis基本命令:https://blog.csdn.net/HJW_233/article/details/131902164

参考文章:https://www.jianshu.com/p/cb6fb8f8bb83

1. 引入pom

  
      org.springframework.boot
      spring-boot-starter-data-redis
  

2. 增加配置

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456

3. 自定义序列化

TODO: list 存储的对象还是存储的字节数组?

如果不自定义自定义序列化方式的话,查看缓存数据的时候是字节数组,看不懂!

OMS系统的配置

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
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.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
 * redis配置
 *
 * @author 
 * @date 2021/12/7 3:07 下午
 */
@Configuration
@EnableCaching
public class RedisConfig {
    /**
     * 长时过期时间(秒)
     */
    private static final int REDIS_LONG_EXPIRATION = 86400 * 5; // 24小时 * 5 = 5天
    /**
     * 定义长时的缓存器
     *
     * @return
     */
    @Bean(name = "longLifeCacheManager")
    public CacheManager longLifeCacheManager(RedisConnectionFactory factory) {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(REDIS_LONG_EXPIRATION))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(this.getJacksonRedisSerializer()))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
    /**
     * redisTemplate
     *
     * @param
     * @return org.springframework.data.redis.core.RedisTemplate
     * @author xiefengsong
     * @date 2020/4/26 9:57 上午
     */
    @Bean
    RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate template = new RedisTemplate();
        //连接工厂
        template.setConnectionFactory(redisConnectionFactory);
        //序列化
        Jackson2JsonRedisSerializer serializer = this.getJacksonRedisSerializer();
        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
    /**
     * 配置序列化
     *
     * @param
     * @return org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
     * @author xiefengsong
     * @date 2020/4/26 9:43 上午
     */
    private Jackson2JsonRedisSerializer getJacksonRedisSerializer() {
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //采用的是自由放任所有的通行
        mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        return serializer;
    }
}

参考文章的配置:

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.cache.annotation.EnableCaching;
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.StringRedisSerializer;
/**
 * 

* *

* * @author tianjiaxin * @createTime 2024/6/3 11:27 * @Description: */ @Configuration @EnableCaching public class RedisConfig { @Bean("redisTemplate") public RedisTemplate initRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate redisTemplate = new RedisTemplate(); // 设置连接工厂 redisTemplate.setConnectionFactory(redisConnectionFactory); // 定义 String 序列化器 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // 定义 Jackson 序列化器 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); //反序列化时智能识别变量名(识别没有按驼峰格式命名的变量名) objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); //反序列化识别对象类型 objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); // objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY); //反序列化如果有多的属性,不抛出异常 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //反序列化如果碰到不识别的枚举值,是否作为空值解释,true:不会抛不识别的异常, 会赋空值,false:会抛不识别的异常 objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 设置 Redis 的 key 以及 hash 结构的 field 使用 String 序列化器 redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); // 设置 Redis 的 value 以及 hash 结构的 value 使用 Jackson 序列化器 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } }

4. 基本类型操作

package com.tjx.service.impl;
import com.tjx.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * 

* *

* * @author tianjiaxin * @createTime 2024/6/3 14:20 * @Description: */ @Service public class MyRedisServiceImpl { @Autowired RedisTemplate redisTemplate; @Autowired StringRedisTemplate stringRedisTemplate; // 基本操作 public void test1() { stringRedisTemplate.opsForValue().set("srt", "StringRedisTemplate"); redisTemplate.opsForValue().set("test1", new User(1L, "tjx", 18)); redisTemplate.opsForSet().add("set", "1", "2"); Boolean member = redisTemplate.opsForSet().isMember("set", "1"); System.out.println("==========" + member); redisTemplate.opsForList().leftPush("list", new User(2L, "小明", 19)); redisTemplate.opsForList().leftPush("list", new User(3L, "小红", 19)); redisTemplate.opsForList().rightPop("list"); } // 对一个key多次操作 public void test2() { BoundSetOperations bound = redisTemplate.boundSetOps("bound"); bound.add("1"); bound.add("2"); } // 事务 public void test3() { stringRedisTemplate.opsForValue().set("stock", "1000"); List results = stringRedisTemplate.execute(new SessionCallback() { @Override public List execute(RedisOperations redisOperations) throws DataAccessException { // 监控库存 redisOperations.watch((K) "stock"); // 获取库存 int stock = Integer.parseInt(String.valueOf(redisOperations.opsForValue().get("stock"))); // 如果库存在于购买数量,则库存构建,否则返回null if (stock > 10) { stock -= 10; } else { redisOperations.unwatch(); return null; } // 开启事务 redisOperations.multi(); // 扣减库存 redisOperations.opsForValue().set((K) "stock", (V) String.valueOf(stock)); // 执行事务 List exec = redisOperations.exec(); return exec; } }); if (results == null || results.size() == 0) { System.out.println("库存扣减失败!"); } else { System.out.println("剩余库存:" + stringRedisTemplate.opsForValue().get("stock")); } } // pipeline 多个命令批量发送都服务器上,减少网络传输 public void test4() { stringRedisTemplate.executePipelined(new SessionCallback() { @Override public Object execute(RedisOperations redisOperations) throws DataAccessException { stringRedisTemplate.opsForValue().set("pipeline1", "1"); stringRedisTemplate.opsForValue().set("pipeline2", "2"); stringRedisTemplate.opsForValue().set("pipeline3", "3"); return null; } }); } }

5. 搭配注解自动写入缓存

注意:在配置文件中添加@EnableCaching注解,其他配置还有依赖不需要添加

cacheNames:相当于key的前缀,含义是缓存存储的名称

SpringBoot集成Redis

  • @CacheConfig,在类上使用,表示该类中方法使用的缓存名称(可以理解为数据缓存的命名空间),除了在类上使用该注解配置缓存名称,还可以用下边三个注解在方法上配置
  • @CachePut,一般用在新增或更新业务的方法上,当数据新增或更新成功后,将方法的返回结果使用指定的 key 添加到缓存中,或更新缓存中已有的 key 的值
  • @Cacheable,一般用在查询业务的方法上,先从缓存中根据指定的 key 查询数据,如果查询到就直接返回,否则执行该方法来获取数据,最后将方法的返回结果保存到缓存
  • @CacheEvict,一般用在删除业务的方法上,默认会在方法执行结束后移除指定 key 对应的缓存数据
    package com.tjx.service.impl;
    import com.tjx.dao.entity.StudentsDO;
    import com.tjx.dao.mapper.StudentsMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.annotation.CacheConfig;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Service;
    /**
     * 

    * *

    * * @author tianjiaxin * @createTime 2024/6/3 17:18 * @Description: */ @Service @CacheConfig(cacheNames = "studentSercieImpl") public class StudentServiceImpl { @Autowired StudentsMapper studentsMapper; @Cacheable(cacheNames = "getStudentsById", key = "'student' + #id") public StudentsDO getStudentsById(Integer id) { return studentsMapper.selectById(id); } @CachePut(key = "'student' + #studentsDO.id") public StudentsDO addStudents(StudentsDO studentsDO) { studentsMapper.insert(studentsDO); return studentsDO; } @CachePut(key = "'student' + #studentsDO.id", condition = "#result != 'null'") public StudentsDO updateStudents(StudentsDO studentsDO) { if (studentsDO == null) return null; studentsMapper.updateById(studentsDO); return studentsDO; } @CacheEvict(cacheNames = "delete", key = "'student' + #id") public Integer deleteUserById(Integer id) { return studentsMapper.deleteById(id); } }

    6. 基本操作工具类

    package com.xiaomi.mit.oms.order.components.cache.manager;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    import org.springframework.util.CollectionUtils;
    import java.io.Serializable;
    import java.util.*;
    import java.util.concurrent.TimeUnit;
    @Slf4j
    @Component
    public class RedisManager {
        @Autowired
        private RedisTemplate redisTemplate;
        public boolean expire(String key, long time) {
            try {
                if (time > 0) {
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
                return true;
            } catch (Exception e) {
                log.error("[Redis] 设置key过期时间异常, key:{}, time:{}", key, time, e);
                return false;
            }
        }
        public long getExpire(String key) {
            return redisTemplate.getExpire(key, TimeUnit.SECONDS);
        }
        public boolean hasKey(String key) {
            try {
                return redisTemplate.hasKey(key);
            } catch (Exception e) {
                log.warn("[Redis] 查询key值异常, key:{}", key, e);
                return false;
            }
        }
        public boolean delete(String key) {
            return redisTemplate.delete(key);
        }
        public void delete(String... key) {
            if (key != null && key.length > 0) {
                if (key.length == 1) {
                    redisTemplate.delete(key[0]);
                } else {
                    redisTemplate.delete(CollectionUtils.arrayToList(key));
                }
            }
        }
        /**
         * 根据pattern删除
         *
         * @param pattern
         */
        public void deleteByPattern(String pattern) {
            Set keys = redisTemplate.keys(pattern);
            if (keys != null && keys.size() > 0) {
                redisTemplate.delete(keys);
            }
        }
        public List mGet(Collection keys) {
            return redisTemplate.opsForValue().multiGet(keys);
        }
        public Object get(String key) {
            return key == null ? null : redisTemplate.opsForValue().get(key);
        }
        /**
         * 普通缓存获取
         *
         * @param key 键
         * @return 值
         */
        public String getString(String key) {
            return key == null ? null : (String) redisTemplate.opsForValue().get(key);
        }
        public boolean set(String key, Object value) {
            try {
                redisTemplate.opsForValue().set(key, value);
                return true;
            } catch (Exception e) {
                log.error("[Redis] set设置key值异常, key:{}, value:{}", key, value, e);
                return false;
            }
        }
        public boolean set(String key, Object value, long time) {
            try {
                if (time > 0) {
                    redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
                } else {
                    set(key, value);
                }
                return true;
            } catch (Exception e) {
                log.error("[Redis] set设置key值异常, key:{}, value:{}, time:{}", key, value, time, e);
                return false;
            }
        }
        public boolean setNx(String key, Object value, long time) {
            if (time  0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                log.error("[Redis] Map设置异常, key:{}, map:{}, time:{}", key, map, time, e);
                return false;
            }
        }
        public boolean hmSet(String key, String item, Object value) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                return true;
            } catch (Exception e) {
                log.error("[Redis] Map设置字段值异常, key:{}, item:{}, value:{}", key, item, value, e);
                return false;
            }
        }
        public boolean hmSet(String key, String item, Object value, long time) {
            try {
                redisTemplate.opsForHash().put(key, item, value);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                log.error("[Redis] Map设置字段值异常, key:{}, item:{}, value:{}, time:{}", key, item, value, time, e);
                return false;
            }
        }
        public void hmDelete(String key, Object... item) {
            redisTemplate.opsForHash().delete(key, item);
        }
        public boolean hmHasKey(String key, String item) {
            return redisTemplate.opsForHash().hasKey(key, item);
        }
        public double hmIncr(String key, String item, double by) {
            return redisTemplate.opsForHash().increment(key, item, by);
        }
        public double hmDecr(String key, String item, double by) {
            return redisTemplate.opsForHash().increment(key, item, -by);
        }
        // ============================set=============================
        public Set sGet(String key) {
            try {
                return redisTemplate.opsForSet().members(key);
            } catch (Exception e) {
                log.error("[Redis] 根据key值获取Set异常, key:{}", key, e);
                return Collections.emptySet();
            }
        }
        public boolean sHasKey(String key, Object value) {
            try {
                return redisTemplate.opsForSet().isMember(key, value);
            } catch (Exception e) {
                log.error("[Redis] 根据key查询Set中是否存在value值异常, key:{}, value:{}", key, value, e);
                return false;
            }
        }
        public long sSet(String key, Object... values) {
            try {
                return redisTemplate.opsForSet().add(key, values);
            } catch (Exception e) {
                log.error("[Redis] 根据key查询Set中是否存在多个value值异常, key:{}, value:{}", key, values, e);
                return 0;
            }
        }
        public long sSetAndTime(String key, long time, Object... values) {
            try {
                Long count = redisTemplate.opsForSet().add(key, values);
                if (time > 0) {
                    expire(key, time);
                }
                return count;
            } catch (Exception e) {
                log.error("[Redis] Set设置多个值并设置过期时间异常, key:{}, value:{}, time:{}", key, values, time, e);
                return 0;
            }
        }
        public long sGetSetSize(String key) {
            try {
                return redisTemplate.opsForSet().size(key);
            } catch (Exception e) {
                log.error("[Redis] Set根据key值查询size异常, key:{}", key, e);
                return 0;
            }
        }
        public long setRemove(String key, Object... values) {
            try {
                return redisTemplate.opsForSet().remove(key, values);
            } catch (Exception e) {
                log.error("[Redis] Set根据key删除多个value异常, key:{}, value:{}", key, values, e);
                return 0L;
            }
        }
        public List lGet(String key, long start, long end) {
            try {
                return redisTemplate.opsForList().range(key, start, end);
            } catch (Exception e) {
                log.error("[Redis] List根据key查询对象异常, key:{}, start:{}, end:{}", key, start, end, e);
                return Collections.emptyList();
            }
        }
        /**
         * 获取list缓存的内容,取出所有的值
         *
         * @param key 键
         * @return
         */
        public List lGet(String key) {
            try {
                return redisTemplate.opsForList().range(key, 0, -1);
            } catch (Exception e) {
                log.error("[Redis] List根据key查询对象异常, key:{}, start:{}, end:{}", key, 0, -1, e);
                return Collections.emptyList();
            }
        }
        public long lGetListSize(String key) {
            try {
                return redisTemplate.opsForList().size(key);
            } catch (Exception e) {
                log.error("[Redis] List根据key查询对象size异常, key:{}", key, e);
                return 0;
            }
        }
        public Object lGetIndex(String key, long index) {
            try {
                return redisTemplate.opsForList().index(key, index);
            } catch (Exception e) {
                log.error("[Redis] List根据key查询index对象异常, key:{}, index:{}", key, index, e);
                return null;
            }
        }
        public boolean rSet(String key, Object value) {
            try {
                redisTemplate.opsForList().rightPush(key, value);
                return true;
            } catch (Exception e) {
                log.error("[Redis] List right push对象异常, key:{}, value:{}", key, value, e);
                return false;
            }
        }
        public boolean rSet(String key, Object value, long time) {
            try {
                redisTemplate.opsForList().rightPush(key, value);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                log.error("[Redis] List right push对象异常, key:{}, value:{}, time:{}", key, value, time, e);
                return false;
            }
        }
        public boolean rSet(String key, List value) {
            try {
                redisTemplate.opsForList().rightPushAll(key, value);
                return true;
            } catch (Exception e) {
                log.error("[Redis] List right push list对象异常, key:{}, value:{}", key, value, e);
                return false;
            }
        }
        public boolean rSet(String key, List value, long time) {
            try {
                redisTemplate.opsForList().rightPushAll(key, value);
                if (time > 0) {
                    expire(key, time);
                }
                return true;
            } catch (Exception e) {
                log.error("[Redis] List right push list对象异常, key:{}, value:{}, time:{}", key, value, time, e);
                return false;
            }
        }
        public boolean lUpdateIndex(String key, long index, Object value) {
            try {
                redisTemplate.opsForList().set(key, index, value);
                return true;
            } catch (Exception e) {
                log.error("[Redis] List根据索引更新对象异常, key:{}, index:{}, value:{}", key, index, value, e);
                return false;
            }
        }
        public long lRemove(String key, long count, Object value) {
            try {
                return redisTemplate.opsForList().remove(key, count, value);
            } catch (Exception e) {
                log.error("[Redis] List 删除指定个数对象异常, key:{}, count:{}, value:{}", key, count, value, e);
                return 0;
            }
        }
    }
    
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]