前言

SpringBoot应该不用过多介绍了吧!是Spring当前最火的一个框架,既然学习了Redis,我们肯定是要在实际项目中使用,那么肯定首选整合SpringBoot啦!

简单介绍下SpringBoot对Jedis的支持吧,在1.×版本的时候,SpringBoot的底层还是使用Jedis来连接Redis的,但是在2.×版本后,就换成了Lettuce。两者的区别如下:
Jedis: 采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用 jedis pool 连接池! 更像 BIO 模式!
Lettuce: 采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像 NIO 模式!

  1. 添加POM依赖:
 <dependencies><!--集成redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.1.7.RELEASE</version></dependency><!--序列化--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.54</version><scope>compile</scope></dependency><!--lombok,自动生成set、get等方法--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version><scope>compile</scope></dependency>
  1. 配置连接的application.yml文件:
server:port: 10001spring:redis:host: 127.0.0.1port: 6379
  1. 测试连接:我们写个测试方法来进行最基本的连接测试!
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;@SpringBootTest
public class testRedis {@Autowired(required = false)private RedisTemplate redisTemplate;@Testvoid getName(){redisTemplate.opsForValue().set("name","dadadingdada!");System.out.println(redisTemplate.opsForValue().get("name"));}
}

运行效果如下!证明Redis连接成功!并且加数据获取数据也成功了!

  1. 其他方法如下:
// redisTemplate  #操作不同的数据类型,api和我们的指令是一样的
// opsForValue  #操作字符串 类似String
// opsForList  #操作List 类似List
// opsForSet  #操作set
// opsForHash  #操作hash
// opsForZSet  #操作zset
// opsForGeo   #操作geo
// opsForHyperLogLog  #操作HyperLogLog
// 除了进本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务,和基本的 CRUD
// 获取redis的连接对象
// RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
// connection.flushDb();
// connection.flushAll();

证明如果是用基本RedisTemplate类来操作Redis的话,是基本上可以达到所有的效果的,因为具体方法和命令大体一致!

  1. 对象的保存和读取
    新增一个User类:
import lombok.Data;@Data
public class User {private String name;private Integer age;private Integer high;
}

测试代码如下:

@Testvoid setObject(){User user = new User();user.setName("dingdada");user.setAge(23);user.setHigh(172);redisTemplate.opsForValue().set("user",user);System.out.println(redisTemplate.opsForValue().get("user"));}

报错如下:

结论:所以在操作Redis中,关于对象的保存我们得序列化才可以正常操作!
6. 自定义封装RedisTemplate类
上面说了大体上可以实现,但是为了在工作中更容易操作Redis,我们一般重新封装RedisTemplate类,如下所示:

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
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.StringRedisSerializer;@Configuration
public class RedisConfig {// 这是我给大家写好的一个固定模板,大家在企业中,拿去就可以直接使用!// 自己定义了一个RedisTemplate@Bean@SuppressWarnings("all")public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {// 我们为了自己开发方便,一般直接使用 <String, Object>RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();template.setConnectionFactory(factory);// Json序列化配置Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);// String 的序列化StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}
}

序列化完成后我们再试试对象的添加获取:

NICE!一切正常!

  1. 封装RedisUtils类:
    在实际工作中,我们不可能用RedisTemplate 来操作Redis的,因为实在太繁琐,所以我们一般自定义一个RedisUtils工具类来操作Redis!
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;@Component
public final class RedisUtil {@Resourceprivate RedisTemplate<String, Object> redisTemplate;public Set<String> keys(String keys){try {return redisTemplate.keys(keys);}catch (Exception e){e.printStackTrace();return null;}}/*** 指定缓存失效时间* @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) {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((Collection<String>) CollectionUtils.arrayToList(key));}}}/*** 普通缓存获取* @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 值* @return true成功 false失败*/public boolean setnx(String key, Object value) {try {redisTemplate.opsForValue().setIfAbsent(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 value 值* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public boolean setnx(String key, Object value, long time) {try {if (time > 0) {redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);} else {set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 递增* @param key 键* @param delta 要增加几(大于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 delta 要减少几(小于0)* @return*/public long decr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return redisTemplate.opsForValue().increment(key, -delta);}/*** 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) {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)* @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);}/*** 根据key获取Set中的所有值* @param key 键* @return*/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 键* @return*/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代表所有值* @return*/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 键* @return*/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倒数第二个元素,依次类推* @return*/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 值* @return*/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 时间(秒)* @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) {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操作都写在这里了,我们在工作中需要用什么,直接通过RedisUtils来使用即可!

  1. 使用RedisUtils
    ①首先将springboot项目启动起来:

    ②添加Contoller在web上测试添加和获取!

③测试工具类的基本使用:
在谷歌浏览器输入:返回成功

测试获取:获取成功!

9.总结:其实这篇讲了这么多,大家可以发现,SpringBoot真的是极度方便,整合Redis之后我们只需要简单的操作即可完美使用Redis!
但是,前面的内容还都是Redis相关的基础,接下来我将继续整理关于Redis的进阶知识!

Redis扩展:Redis学习汇总

路漫漫其修远兮,吾必将上下求索~
到此关于SpringBoot如何整合Redis的讲解就算告一段落了,如果你认为i博主写的不错!写作不易,请点赞、关注、评论给博主一个鼓励吧**转载请注明出处哦**

Redis(五)整合:SpringBoot如何整合Redis?相关推荐

  1. Shiro框架学习笔记、整合Springboot、redis缓存

    本笔记基于B站UP主不良人编程 目录 1.权限的管理 1.1什么是权限管理 1.2什么是身份认证 1.3什么是授权 2.什么是Shiro 3.Shiro的核心架构 3.1 S核心内容 4.shiro中 ...

  2. Redis主从复制Redis哨兵机制Springboot整合哨兵

    目录 一.Redis主从复制 full resync(全量复制) partial resync(增量复制) 二.Redis主从复制配置 三.哨兵机制原理 每个 Sentinel 都需要定期执行的任务 ...

  3. 10分钟解决Redis安装和Springboot整合

    1.Redis安装 for Windows https://github.com/microsoftarchive/redis/releases 下载完成后双击安装,一直下一步 然后打开Redis安装 ...

  4. redis安装到熟练整合springboot(篇幅较长内容详细)

    尚硅谷课程redis学习笔记 1.在linux下安装redis数据库 这篇文章介绍安装 redis介绍: Redis是一个开源的key-value存储系统. 和Memcached类似,它支持存储的va ...

  5. Nginx安装配置与SpringBoot项目整合

    本篇文章将在上篇<Redis安装与SpringBoot项目整合详细教程>(上文链接:https://blog.csdn.net/sp958831205/article/details/88 ...

  6. 字符动图_图解redis五种数据结构底层实现(动图哦)

    redis有五种基本数据结构:字符串.hash.set.zset.list.但是你知道构成这五种结构的底层数据结构是怎样的吗?今天我们来花费五分钟的时间了解一下.(目前redis版本为3.0.6) 动 ...

  7. SpringBoot自动配置Redis原理

    SpringBoot自动配置Redis原理 目录 SpringBoot自动配置Redis原理 一.SpringBoot自动配置Redis原理 一.自动配置redis RedisAutoConfigur ...

  8. 图解redis五种数据结构底层实现

    redis有五种基本数据结构:字符串.hash.set.zset.list.但是你知道构成这五种结构的底层数据结构是怎样的吗?今天我们来花费五分钟的时间了解一下.(目前redis版本为3.0.6) 动 ...

  9. redis进阶之SpringBoot整合Redis(五)

    在聊 SpringBoot整合redis之前,我们先看看 Redis推荐的java连接开发工具:jedis知其然并知其所以然,授人以渔! 学习不能急躁,慢慢来会很快! Jedis 什么是Jedis 是 ...

最新文章

  1. Keras【Deep Learning With Python】更优模型探索Keras实现CNN
  2. JavaScript代理模式
  3. 在线学习(Online Learning)
  4. 常用16种视图切换动画
  5. React.js 开发常见问题
  6. 合肥中学计算机老师招聘,2019年合肥北城中学教师招聘公告
  7. Mendix:低代码开发平台 让未来工作模式日渐明朗
  8. “阿里离职女高管”二次回应质疑:晒股票、期权等证据
  9. axios async/await
  10. BootStrap修改modal模态框的宽度
  11. C#用串口接收事件接不全数据的处理
  12. 如何使用iMazing将iPhone的数据迁移到iPad
  13. 基于自抗扰控制的高速列车自动驾驶速度控制
  14. adm怎么下bt连接_BT宝塔FTP连接不上用不了的解决办法,轻松几步设置即可连接...
  15. 【c语言】初识c语言-让你对c语言不在感到一无所知
  16. 【7036】2年前的今晚,我给HR的转岗申请
  17. iOS 二维码生成 (Swift代码)
  18. mybatis拦截器实现update之前根据pk字段校验数据有效性
  19. Codeforces Round 775(Div.2) Problem C Weird Sum(匿名函数的使用)
  20. 自学前端需要达到什么水平才能去找工作?来看看这套前端学习路线图

热门文章

  1. 【pytorch】错误:No module named ‘typing_extensions‘ 问题解决
  2. 细细品味C#——泛型系列专题
  3. P1455 搭配购买
  4. 用户数据报协议---UDP协议【详解】
  5. 通往真理的最短路径 - 【复数】科普/详解
  6. 飞思卡尔智能车 电机PID
  7. 会计基础-会计科目+会计账户+复式记账+会计分录+会计凭证
  8. 国际经济学 简答计算
  9. ai文字渐变_AI文字教程,用AI制作立体渐变环绕文字
  10. Docker 详细教程