redis笔记——springboot集成redis

news/2025/1/16 1:34:45/

Sprigboot整合

springboot整合数据操作一般会通过官方的一个项目springdata来进行整合,它可以操作很多市面上流行的数据库,并且为java程序提供一套完整的统一的api调用。在springboot2版本之后,原本的jedis被替换成功了lettuce。原因是

  • jedis底层是直接reids服务的,多个线程操作不够安全,但如果采用jedis pool连接池又会发生很多问题比如服务占用过大
  • lettuce底层采用netty,一个实例可以在多个线程中共享,不存在线程不安全

原生使用

导入依赖之后在需要使用的类上注入redisTemplate实例即可

package com.zhong;import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;import javax.annotation.Resource;@SpringBootTest
class Redis02SpringbootApplicationTests {//注入操作redis的实例对象@Resourceprivate RedisTemplate redisTemplate;@Testvoid contextLoads() {//		redisTemplate.opsForValue(); //操作string类型
//		redisTemplate.opsForList(); //操作list类型
//		redisTemplate.opsForSet();
//		redisTemplate.opsForZSet();
//		redisTemplate.opsForHash();
//		redisTemplate.opsForGeo();
//		redisTemplate.opsForHyperLogLog();
//		RedisConnection connection = redisTemplate.getConnectionFactory().getConnection(); //获得连接,清空数据库都是通过这个连接来进行的
//		connection.flushDb();
//		connection.flushAll();redisTemplate.opsForValue().set("key", "你好,redis");System.out.println(redisTemplate.opsForValue().get("key"));}}

原生客户端连接获取java程序中传递的值会出现中文乱码

在使用java程序对redis注入kv之后,使用redis-cli连接上redis数据库,查看所有的key发现出现了乱码。

127.0.0.1:6379> keys *
1) "user1"
2) "user2"
3) "\xac\xed\x00\x05t\x00\x03key"

这是由于默认的redisTemplate使用的是jdk的序列化,所以就会出现这样的问题。并且如果ava向redis中传递对象,需要把对象序列化才能传递。,或者使用json格式包装对象。我们需要自定义一个序列化方式,于是我们需要自己配置一个redisTemplate。

package com.zhong.config;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.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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {//为了开发方便一般使用string,objectRedisTemplate<String, Object> template = new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);//json序列化配置(采用fastjson)Jackson2JsonRedisSerializer objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);objectJackson2JsonRedisSerializer.setObjectMapper(om);//string序列化配置StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//设置普通key的序列化方式为string序列化template.setKeySerializer(stringRedisSerializer);//设置hash的key的序列化方式为string序列化template.setHashKeySerializer(stringRedisSerializer);//设置普通value序列化方式为json序列化template.setValueSerializer(objectJackson2JsonRedisSerializer);//设置hash的value的序列化方式为json序列化template.setHashValueSerializer(objectJackson2JsonRedisSerializer);template.afterPropertiesSet();//新版本可以直接new这个实例作为json序列化方式,默认配置好了配置GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();return template;}
}

测试

package com.zhong;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhong.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;import javax.annotation.Resource;@SpringBootTest
class Redis02SpringbootApplicationTests {@Resource@Qualifier("redisTemplate")private RedisTemplate redisTemplate;@Testpublic void TestObject() throws JsonProcessingException {User zhong = new User("zhong", 3);
//    String s = new ObjectMapper().writeValueAsString(zhong);redisTemplate.opsForValue().set("user", zhong);System.out.println(redisTemplate.opsForValue().get("user"));}}
127.0.0.1:6379> keys *
1) "user"
127.0.0.1:6379> get user
"[\"com.zhong.pojo.User\",{\"name\":\"zhong\",\"age\":3}]"

发现在原来的reidis客户端中也能正常显示中文了

封装工具类

在原生的redisTemplate代码中使用get和set方法过于麻烦,我们可以使用一些封装好的工具类来简化操作,在工具类中直接注入我们自定义好的redisTemplate,并且将这个工具类注册为组件,方便我们在后来的类中直接注入而不是new出来

package com.zhong.utils;import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;/*** @author pancm* @Title: RedisUtil* @Description: redis工具类* @Version:1.0.0* @date 2018年6月7日*/
@Component
@Slf4j
public class RedisUtil {@Resourceprivate RedisTemplate<String, Object> redisTemplate;// =============================common============================/*** 指定缓存失效时间** @param key  键* @param time 时间(秒)* @return*/public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 判断key是否过期** @param key* @return*/public boolean isExpire(String key) {return getExpire(key) > 1 ? false : true;}/*** 根据key 获取过期时间** @param key 键 不能为null* @return 时间(秒) 返回0代表为永久有效*/public long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断key是否存在** @param key 键* @return true 存在 false不存在*/public boolean hasKey(String key) {try {return redisTemplate.hasKey(key);} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 删除缓存** @param key 可以传一个值 或多个*/@SuppressWarnings("unchecked")public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));}}}// ============================String=============================/*** 普通缓存获取** @param key 键* @return 值*/public Object get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通缓存放入** @param key   键* @param value 值* @return true成功 false失败*/public boolean set(String key, Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 普通缓存放入并设置时间** @param key   键* @param value 值* @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 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(e.getMessage());return false;}}/*** 普通缓存放入并设置时间** @param key   键* @param value 值* @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public boolean set(String key, Object value, long time, TimeUnit timeUnit) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, timeUnit);} else {set(key, value);}return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 递增** @param key 键* @param by  要增加几(大于0)* @return*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 递减** @param key 键* @param by  要减少几(小于0)* @return*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return redisTemplate.opsForValue().increment(key, -delta);}// ================================Map=================================/*** HashGet** @param key  键 不能为null* @param item 项 不能为null* @return 值*/public Object hget(String key, String item) {return redisTemplate.opsForHash().get(key, item);}/*** 获取hashKey对应的所有键值** @param key 键* @return 对应的多个键值*/public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);}/*** HashSet** @param key 键* @param map 对应多个键值* @return true 成功 false 失败*/public boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** HashSet 并设置时间** @param key  键* @param map  对应多个键值* @param time 时间(秒)* @return true成功 false失败*/public boolean hmset(String key, Map<String, Object> map, long time) {try {redisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @return true 成功 false失败*/public boolean hset(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间* @return true 成功 false失败*/public boolean hset(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(e.getMessage());return false;}}/*** 删除hash表中的值** @param key  键 不能为null* @param item 项 可以使多个 不能为null*/public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);}/*** 判断hash表中是否有该项的值** @param key  键 不能为null* @param item 项 不能为null* @return true 存在 false不存在*/public boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}/*** hash递增 如果不存在,就会创建一个 并把新增后的值返回** @param key  键* @param item 项* @param by   要增加几(大于0)* @return*/public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash递减** @param key  键* @param item 项* @param by   要减少记(小于0)* @return*/public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);}// ============================set=============================/*** 根据key获取Set中的所有值** @param key 键* @return*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {log.error(e.getMessage());return null;}}/*** 根据value从一个set中查询,是否存在** @param key   键* @param value 值* @return true 存在 false不存在*/public boolean sHasKey(String key, Object value) {try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 将数据放入set缓存** @param key    键* @param values 值 可以是多个* @return 成功个数*/public long sSet(String key, Object... values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {log.error(e.getMessage());return 0;}}/*** 将set数据放入缓存** @param key    键* @param time   时间(秒)* @param values 值 可以是多个* @return 成功个数*/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(e.getMessage());return 0;}}/*** 获取set缓存的长度** @param key 键* @return*/public long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {log.error(e.getMessage());return 0;}}/*** 移除值为value的** @param key    键* @param values 值 可以是多个* @return 移除的个数*/public long setRemove(String key, Object... values) {try {Long count = redisTemplate.opsForSet().remove(key, values);return count;} catch (Exception e) {log.error(e.getMessage());return 0;}}// ===============================list=================================/*** 获取list缓存的内容** @param key   键* @param start 开始* @param end   结束 0 到 -1代表所有值* @return*/public List<Object> lGet(String key, long start, long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {log.error(e.getMessage());return null;}}/*** 获取list缓存的长度** @param key 键* @return*/public long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {log.error(e.getMessage());return 0;}}/*** 通过索引 获取list中的值** @param key   键* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推* @return*/public Object lGetIndex(String key, long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {log.error(e.getMessage());return null;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(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(e.getMessage());return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return*/public boolean lSet(String key, List<Object> value, long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 根据索引修改list中的某条数据** @param key   键* @param index 索引* @param value 值* @return*/public boolean lUpdateIndex(String key, long index, Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {log.error(e.getMessage());return false;}}/*** 移除N个值为value** @param key   键* @param count 移除多少个* @param value 值* @return 移除的个数*/public long lRemove(String key, long count, Object value) {try {Long remove = redisTemplate.opsForList().remove(key, count, value);return remove;} catch (Exception e) {log.error(e.getMessage());return 0;}}}

http://www.ppmy.cn/news/47942.html

相关文章

Java读取文件方式

IO流读取 文本内容 按行读取文件内容 指定编码格式&#xff08;推荐&#xff09; public static void main(String[] args) throws UnsupportedEncodingException {read("D:\\test.txt");}public static void read(String path) {BufferedReader reader null;try …

DNS服务器 - 理论

DNS服务器 1. 概念2. DNS域名结构3. 域名的分级4. 域名服务器4.1 层次结构4.2 DNS服务类型 5. 域名解析过程5.1 递归查询与迭代查询5.2 解析流程1. 迭代查询2. 递归查询 6. 高速缓存7. 加上主机缓存后的DNS解析流程8. 常见的域名解析记录9. DNS正向解析和反向解析10. 配置文件介…

Ubuntu上跑通PaddleOCR

书接上文。刚才说到我已经在NUC8里灌上了Windows Server 2019。接下来也顺利的启用了Hyper-V角色并装好了一台Ubuntu 22.04 LTS 的虚机。由于自从上回在树莓派上跑通了Paddle-Lite-Demo之后想再研究一下PaddleOCR但进展不顺&#xff0c;因此决定先不折腾了&#xff0c;还是从x6…

vs = VirtualService

VirtualService 您是正确的。我混淆了Kubernetes中的资源类型。"vs"是Istio服务网格中的资源类型&#xff0c;代表Virtual Service&#xff08;虚拟服务&#xff09;。 Virtual Service是Istio中的一种路由规则&#xff0c;它定义了如何将请求路由到服务的不同版本…

2023年 中国制造业这三大趋势不可忽视

政府要掏1个亿奖励制造企业搞发展&#xff0c;我国制造业大翻身的时代来了吗&#xff1f; 4月12日成都日报电&#xff0c;为支持制造业创新发展&#xff0c;支持制造业数字化、智能化和绿色化转型升级&#xff0c;培育高精尖特企业&#xff0c;政府给扶持政策不说&#xff0c;…

如何快速查找下载外文文献,哪个文献下载网站好用

​​如何高效获取到自己需要的外文文献&#xff0c;最好的办法就是去文献来源数据库中查找&#xff0c;你需要的文献来源数据库有可能是Elsevier&#xff08;sciencedirect&#xff09;、也可能是Wiley Online Library、也有可能是IEEE等等&#xff0c;外文数据库机构太多了。这…

C语言入门篇——数据篇

目录 1、变量与常量 1.1变量 1.2常量 1.2.1#define 定义的标识符常量 1.2.2枚举常量 2、数据类型关键字 3、整数 4、浮点数 5、基本数据类型 5.1、int型数据 5.2、char型数据 5.3、_Bool类型 5.4、float、double和long double 5.5、复数和虚数类型 6、总结 1、变…

Springboot基础学习之(二十三):实现定时任务

定时任务&#xff1a;在开发过程中是经常能够使用到的&#xff1a;定时发布邮件等等 先了解一下什么时cron表达式&#xff1f; 它是定义执行任务时间的一种时间表达式&#xff0c;使用方法 Scheduled(cron "0/2 * * * * ? ")&#xff0c;这里代码的含义是每两秒执行…