Redis学习笔记(二)

  • SpringBoot整合
    • 测试
      • 导入依赖
        • 查看底层
      • 配置连接
      • 测试连接
    • 自定义`RedisTemplate`
      • 在开发中,一般都是以json来传输对象:
      • 所以实际开发中所有对象需序列化
      • 自定义`RedisTemplate`模板
    • 编写自定义工具类`MyUtils `

SpringBoot整合

测试

导入依赖

<!--操作redis-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

查看其底层:

 <dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>2.6.0</version><scope>compile</scope></dependency><dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.1.5.RELEASE</version><scope>compile</scope></dependency>

SpringBoot 2.x后,原来的jredis被替换成lettuce

  • Jedis: 采用的直连,多个线程操作不安全,如果想要避免不安全的,使用 jedis pool 连接池!类似 BIO 模式!
  • Lettuce: 采用netty实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,类似 NIO 模式!

查看底层

  1. autoconfigure包中进入spring.factory文件找到redis的自动装配类
  2. 进入后发现绑定了RedisProperties.class文件进行自动装配,以及提供了两个模板:
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {public RedisAutoConfiguration() {}@Bean@ConditionalOnMissingBean(name = {"redisTemplate"})//默认的RedisTemplate没有太多配置,redis对象都需要序列化
//两个泛型都是object,使用时候回强转<string,object>@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);return template;}//由于string在redis使用频率高,所以单独提出了这个bean@Bean@ConditionalOnMissingBean@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {return new StringRedisTemplate(redisConnectionFactory);}
}

配置连接

# 配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379

测试连接

@SpringBootTest
class Redis02SpringbootApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid contextLoads() {/*  //基础命令redisTemplate.opsForValue().set("k1","v1");redisTemplate.opsForList();redisTemplate.opsForGeo();redisTemplate.opsForGeo();redisTemplate.opsForHyperLogLog();redisTemplate.exec();redisTemplate.discard();redisTemplate.multi();//获取redis连接对象RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();connection.flushAll();connection.flushDb();
*/redisTemplate.opsForValue().set("name","yeyu");System.out.println(redisTemplate.opsForValue().get("name"));}}

自定义RedisTemplate

  • RedisAutoConfiguration.class中查看默认RedisTemplate序列化源码


在开发中,一般都是以json来传输对象:

    @Testpublic void  jsonTest() throws JsonProcessingException {User user = new User("夜雨", 18);String jsonUser = new ObjectMapper().writeValueAsString(user);redisTemplate.opsForValue().set("user", jsonUser);System.out.println(redisTemplate.opsForValue().get("user"));}


此处若直接传输对象,则会报错:

所以实际开发中所有对象需序列化

@Component
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User implements Serializable {private String name;private int age;
}

自定义RedisTemplate模板

package com.yue.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {@Bean@SuppressWarnings("all")public RedisTemplate<String, Object> myRedisTemplate(RedisConnectionFactory factory) {//为了开发方便,使用<String, Object>System.out.println("自定义模板开始注入");RedisTemplate<String, Object> template = new RedisTemplate<String,Object>();template.setConnectionFactory(factory);/*配置序列化方式*///1.json序列化配置Jackson2JsonRedisSerializer objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);  #过时 有安全漏洞mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL,JsonTypeInfo.As.WRAPPER_ARRAY);objectJackson2JsonRedisSerializer.setObjectMapper(mapper);//2.String的序列化方式StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();//key 采用string 的序列化方式template.setKeySerializer(stringRedisSerializer);//hash的key也采用string的序列化方式template.setHashKeySerializer(stringRedisSerializer);//value序列化方式采用jacksontemplate.setValueSerializer(objectJackson2JsonRedisSerializer);//hash的value序列化方式采用jacksontemplate.setHashValueSerializer(objectJackson2JsonRedisSerializer);template.afterPropertiesSet();System.out.println("自定义模板已注入");return template;}}

测试:

 @Testpublic void  jsonTest() throws JsonProcessingException {User user = new User("夜雨", 18);/*String jsonUser = new ObjectMapper().writeValueAsString(user);*/redisTemplate.opsForValue().set("user", user);System.out.println(redisTemplate.opsForValue().get("user"));}

前者由自定义模板的String接管
后者由默认jdk序列化,有转义字符

编写自定义工具类MyUtils

因开发中使用redis百分之八十的情况都是get(),set()方法,以及一些基本类型的使用,所以需要写一个工具类来封装,减少日后使用redis的一些麻烦

package com.yue.utils;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;public class MyUtils {@Componentpublic final class RedisUtil {@Autowired@Qualifier("redisTemplate")private RedisTemplate redisTemplate;// =============================common============================/*** 指定缓存失效时间** @param key  键* @param time 时间(秒)*/public boolean expire(String key, long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据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) {e.printStackTrace();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(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) {e.printStackTrace();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) {e.printStackTrace();return false;}}/*** 递增** @param key   键* @param delta 要增加几(大于0)*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 递减** @param key   键* @param delta 要减少几(小于0)*/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*/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 对应多个键值*/public boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {e.printStackTrace();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) {e.printStackTrace();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) {e.printStackTrace();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) {e.printStackTrace();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)*/public double hincr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash递减** @param key  键* @param item 项* @param by   要减少记(小于0)*/public double hdecr(String key, String item, double by) {return redisTemplate.opsForHash().increment(key, item, -by);}// ============================set=============================/*** 根据key获取Set中的所有值** @param key 键*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {e.printStackTrace();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) {e.printStackTrace();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) {e.printStackTrace();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) {e.printStackTrace();return 0;}}/*** 获取set缓存的长度** @param key 键*/public long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {e.printStackTrace();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) {e.printStackTrace();return 0;}}// ===============================list=================================/*** 获取list缓存的内容** @param key   键* @param start 开始* @param end   结束 0 到 -1代表所有值*/public List<Object> lGet(String key, long start, long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取list缓存的长度** @param key 键*/public long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0;}}/*** 通过索引 获取list中的值** @param key   键* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推*/public Object lGetIndex(String key, long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 将list放入缓存** @param key   键* @param value 值*/public boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)*/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) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @return*/public boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {e.printStackTrace();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) {e.printStackTrace();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) {e.printStackTrace();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) {e.printStackTrace();return 0;}}}
}

Redis学习笔记(二)SpringBoot整合相关推荐

  1. SpringBoot学习笔记(16)----SpringBoot整合Swagger2

    Swagger 是一个规范和完整的框架,用于生成,描述,调用和可视化RESTful风格的web服务 http://swagger.io Springfox的前身是swagger-springmvc,是 ...

  2. StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用

    StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用 原文: StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用 Connec ...

  3. Redis学习(含 Springboot 整合 Redis)

    Redis NoSQL (not only sql) 在现代的计算系统上每天网络上都会产生庞大的数据量. 这些数据有很大一部分是由关系数据库管理系统(RDBMS)来处理. 1970年 E.F.Codd ...

  4. springboot学习笔记-5 springboot整合shiro

    shiro是一个权限框架,具体的使用可以查看其官网 http://shiro.apache.org/  它提供了很方便的权限认证和登录的功能. 而springboot作为一个开源框架,必然提供了和sh ...

  5. Redis学习笔记(二) [配置文件,3种新的数据类型,Jedis操作]

    近期计划对redis再进行一段详细的学习, 在B站找到了尚硅谷的redis教学视频->[尚硅谷]Redis 6 入门到精通 超详细 教程,进行学习记录 文章目录

  6. redis学习笔记二

    2019独角兽企业重金招聘Python工程师标准>>> http://redisbook.readthedocs.io/en/latest/ redis为什么会有高并发问题 redi ...

  7. springAop学习笔记(二,springboot进本配置和使用)

    配置 1.引入aop jar包 2.在主类上面加@EnableAspectJAutoProxy 这里要说一句:市面上常用有两种aop实现方式第一种是springaop,第二种是AspectJ,但是原始 ...

  8. Redis学习笔记(B站狂神说)(自己总结方便复习)

    Redis学习笔记B站狂神说 redis: 非关系型数据库 一.NoSQL概述 1.为什么要用Nosql 1.单机Mysql的年代 思考一下,这种情况下:整个网站的瓶颈是什么? 1.数据量如果太大,一 ...

  9. Redis学习笔记①基础篇_Redis快速入门

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 资料链接:https://pan.baidu.com/s/1189u6u4icQYHg_9_7ovWmA( ...

最新文章

  1. Java项目:前台+后台在线考试系统设计和实现(java+Springboot+ssm+mysql+jsp+maven)
  2. 7-CPU Reset
  3. 多路 IO 转接 :epoll 函数
  4. ASP.NET三层架构之不确定查询参数个数的查询
  5. 沃罗诺伊图是怎样的?
  6. python 最优化算法库_哈工大硕士生用?Python 实现了 11 种经典数据降维算法,源代码库已开放...
  7. HTML5 audio
  8. asp.net 获取全部在线用户_提取在线数据的9个最佳网页抓取工具
  9. 解析接口中的JSON数据
  10. CoolBlog开发笔记第2课:搭建开发环境
  11. 一键将RHEL的YUM源更换为CentOS源
  12. 牛客暑期多校第五场A:gpa题解(简单01分数规划)
  13. 从实战进阶系列之DNF脚本实战
  14. 【windows】使用键盘代替鼠标的快捷键
  15. playsound playsound.PlaysoundException: Error 263 for command: open ./dataSet/warn.wav 指定的设备未打开,或不被
  16. javascript 验证 国际格式 电话号码
  17. python计算方位角_利用python计算太阳天顶角、方位角、高度角
  18. 万里无云 满天繁星
  19. OpenCV 保存视频
  20. 如何自学成为设计师_自学能成为一名平面设计师吗?如何提高审美?

热门文章

  1. 拍照翻译的软件有什么?快把这些软件收好
  2. mysql5.7乱码_解决Mysql5.7中文乱码的问题
  3. 买了调节阀,知道怎么调试吗
  4. Android进阶-百度地图申请key规范和230,200,no config chosen分析解决办法。
  5. Foosball桌上足球
  6. Labview菜单实现
  7. OpenJudge noi1805碎纸机
  8. Io流的FileInputStream和FileOutputStream的读取和写入
  9. vue 音乐播放器上一首 下一首切换
  10. 如何使用python脚本自动解锁电脑屏幕