SpringBoot集成Redis
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的前缀,含义是缓存存储的名称
- @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; } } }
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

