SpringBoot--Redis基础知识
文章目录
- SpringBoot--Redis基础知识
-
- 1.Redis简介
- 2.Redis能做什么
- 3.Redis安装(Windows系统)
- 4.SpringBoot项目中使用Redis
-
- 4.1配置Redis
- 4.2使用Spring封装的RedisTemplate操作redis
-
- [4.2.1操作字符串 opsForValue](#4.2.1操作字符串 opsForValue)
- [4.2.2操作list opsForList](#4.2.2操作list opsForList)
- [4.2.3操作有序set opsForZSet](#4.2.3操作有序set opsForZSet)
- [4.2.4操作无序set opsForSet](#4.2.4操作无序set opsForSet)
- [4.2.5操作hash opsForHash](#4.2.5操作hash opsForHash)
- 4.3StringRedisTemplate常用操作
- 5.StringRedisTemplate与RedisTemplate区别
1.Redis简介
redis是一个key-value。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set--有序集合)和hash(哈希类型)。
Redis 内置了复制(replication),LUA脚本(Luascripting),LRU驱动事件(LRU eviction),事务(transactions)和不同级别的 磁盘持久化(persistence),并通过Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性(high availability)。
2.Redis能做什么
- 缓存,毫无疑问这是Redis当今最为人熟知的使用场景。再提升服务器性能方面非常有效
- 排行榜,利用Redis的SortSet数据结构能够非常方便搞定
- 计算器/限速器,利用Redis中原子性的自增操作,我们可以统计类似用户点赞数、用户访问数等,这类操作如果用MySQL,频繁的读写会带来相当大的压力;限速器比较典型的使用场景是限制某个用户访问某个API的频率,常用的有抢购时,防止用户疯狂点击带来不必要的压力; 注:限速器也是对请求限流的一种实现方式
- 好友关系,利用集合的一些命令,比如求交集、并集、差集等。可以方便搞定一些共同好友、共同爱好之类的功能
- 简单消息队列,除了Redis自身的发布/订阅模式,我们也可以利用List来实现一个队列机制,比如:到货通知、邮件发送之类的需求,不需要高可靠,但是会带来非常大的DB压力,完全可以用List来完成异步解耦
- Session共享,默认Session是保存在服务器的文件中,即当前服务器,如果是集群服务,同一个用户过来可能落在不同机器上,这就会导致用户频繁登陆;采用Redis保存Session后,无论用户落在那台机器上都能够获取到对应的Session信息
3.Redis安装(Windows系统)
- 下载包 https://github.com/MicrosoftArchive/redis/releases
- 解压到D盘目录下
3.1启动Redis
-
在解压后的目录下cmd,直接输入命令redis-server.exe redis.windows.conf,即可启动redis
-
新建记事本文件startup.bat, 输入redis-server.exe redis.windows.conf

3.2修改密码
- Redis默认没有密码,若想设置密码解压目录下找到
redis.windows.conf文件中requirepass 下添加requirepass 密码,保存,重新运行即可

4.SpringBoot项目中使用Redis
4.1配置Redis
-
引入相关JAR
xml<!--redis jar--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> -
在application.yml文件中添加相关配置
ymlspring: redis: # Redis服务器地址 host: 127.0.0.1 # Redis数据库端口(默认为6379) port: 6379 # Redis服务器连接密码(默认为空) password: 123456 # Redis数据库索引(默认为0) database: 1 -
完成后,SpringBoot自动在Spring容器中配置一个redisTemplate的Bean,所以可以直接使用redisTemplate
4.2使用Spring封装的RedisTemplate操作redis
常用方法
redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set
4.2.1操作字符串 opsForValue
- 创建opsForValue对象
java
@Autowired
private RedisTemplate redisTemplate;
// 创建opsForValue对象
ValueOperations valueOperations = redisTemplate.opsForValue();
- 存储字符串
java
valueOperations.set("name", "lisi");
System.out.println(redisTemplate.opsForValue().get("name"));
输出结果:lisi
- 设置失效时间
- TimeUnit.DAYS 天
- TimeUnit.HOURS 小时
- TimeUnit.MINUTES 分钟
- TimeUnit.SECONDS 秒
- TimeUnit.MILLISECONDS 毫秒
java
//设置有效期 10秒后过期
valueOperations.set("name","amy",10000, TimeUnit.MILLISECONDS);
// 设置10秒后过期 10秒后,输出null
System.out.println(redisTemplate.opsForValue().get("name"));
- 支持整型与浮点型 (increment)
java
//自增 count=1
valueOperations.increment("count", 1);
//自增 count=2
valueOperations.increment("count", 1);
//输出count=2
System.out.println(valueOperations.get("count"));
- 追加字符串
java
// 追加字符串 name=lisiiii 如果name不存在则创建空字符串 因此APPEND在这种特殊情况下将类似于SET
valueOperations.append("name", "iii");
- 截取key所对应的value字符串
java
// 获取字符串的子串 0-2 包含0不包含2
System.out.println(valueOperations.get("name",0,2));
- 返回key所对应的value值的长度
java
System.out.println(valueOperations.size("name"));
- 存储一个对象 (此类必须先序列化实现接口Serializable)
java
RedisSerializer rs = new StringRedisSerializer();
redisTemplate.setStringSerializer(rs);
Bill bill=new Bill();
bill.setProductName("iphone");
bill.setProductDesc("手机");
bill.setProductUnit("个");
//存储对象 bill 到 redis 中
valueOperations.set("bill",bill);
//获取对象
Bill bill1 = (Bill) valueOperations.get("bill");;
System.out.println(bill1);
输出结果:Bill(id=null, billCode=null, productName=iphone, productDesc=手机, productUnit=个, productCount=null, totalPrice=null, isPayment=null, providerId=null, provider=null)
4.2.2操作list opsForList
- 将所有指定的值插入存储在键的列表的头部;如果键不存在,则在执行推送操作之前将其创建为空列表(从左边插入)
java
//添加数据到list的头部
listOperations.leftPush("names","苏暮雨");
listOperations.leftPush("names","苏昌河");
listOperations.leftPush("names","苏喆");
//[苏喆, 苏昌河, 苏暮雨]
- 将所有指定的值插入存储在键的列表的头部。如果键不存在,则在执行推送操作之前将其创建为空列表。(从右边插入)
java
//添加数据到list的尾部
listOperations.rightPush("names","白鹤淮");
listOperations.rightPush("names","唐怜月");
listOperations.rightPush("names","唐莲");
- 返回存储在键中的列表的指定元素
java
//获取list的所有元素
System.out.println(listOperations.range("names",0,-1));
//输出结果:[苏喆, 苏昌河, 苏暮雨, 白鹤淮, 唐怜月, 唐莲]
-
获取集合长度
System.out.println(listOperations.size("names"));
//输出结果:6 -
在列表中index的位置设置value值(如果index不存在则报错)
//修改list的第4个元素(索引从0开始)
listOperations.set("names",3,"雷云鹤");
System.out.println(listOperations.range("names",0,-1));
输出结果:[苏喆, 苏昌河, 苏暮雨, 雷云鹤, 唐怜月, 唐莲] -
批量将一个数组插入到列表中
java
//批量将一个数组插入到列表中
String[] nameStr = {"萧瑟","无心","苏雨墨"};
listOperations.leftPushAll("names",nameStr);
System.out.println(listOperations.range("names",0,-1));
输出结果:[苏雨墨, 无心, 萧瑟, 苏喆, 苏昌河, 苏暮雨, 雷云鹤, 唐怜月, 唐莲, 白鹤淮, 唐怜月, 唐莲]
- 从存储在键中的列表中删除等于值的元素的第一个计数事件
- count>O:删除等于从头到尾移动的值的元素
- count<0:删除等于从尾到头移动的值的元素
- count=O:删除等于value的所有元素
java
//删除从索引开始,遇到第一个匹配的元素,删除它
listOperations.remove("names",1,"唐莲");
//删除从尾部开始,遇到第一个匹配的元素,删除它
listOperations.remove("names",-1,"白鹤淮");
//删除所有value=唐怜月的的元素
listOperations.remove("names",0,"唐怜月");
-
根据下标获取列表中的值,下标是从0开始的
//获取list的第3个元素(索引从0开始)
System.out.println(listOperations.index("names",2));
4.2.3操作有序set opsForZSet
- 创建 opsForZSet对象
java
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedisTemplate() {
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
}
- 新增一个有序集合
java
zSetOperations.add("zset1","zhangsan",100);
zSetOperations.add("zset1","lisi",88);
zSetOperations.add("zset1","wangwu",99);
- 从有序集合中移除一个或者多个元素
java
//从有序集合中移除一个或者多个元素
zSetOperations.remove("zset1","lisi");
//获取有序集合的所有元素
System.out.println(zSetOperations.range("zset1",0,-1));
输出结果:[wangwu, zhangsan]
- 增加元素的score值,并返回增加后的值
java
//增加有序集合的元素的分数
zSetOperations.incrementScore("zset1","lisi",1);
//获取有序集合的元素的分数
System.out.println(zSetOperations.score("zset1","lisi"));
输出结果:89
- 获取有序集合的元素在有序集合中范围(包含)的索引
java
//获取有序集合的元素在有序集合中范围(包含)的索引
System.out.println(zSetOperations.rangeByScore("zset1",88,100));
//获取有序集合的元素在有序集合中的数量
System.out.println(zSetOperations.count("zset1",88,100));
输出结果:[lisi, wangwu, zhangsan] 3
- 获取有序集合的成员数
java
//获取有序集合的成员数
System.out.println(zSetOperations.size("zset1"));//3
4.2.4操作无序set opsForSet
- 创建opsForSet对象
java
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedisTemplate() {
//创建opsForSet对象
SetOperations setOperations = redisTemplate.opsForSet();
}
- 添加数据
java
//添加数据
String[] strArrays = new String[]{"set1","set2","set3","set4"};
//将元素添加到集合中
setOperations.add("setTest",strArrays);
- 获取集合中的元素
java
//获取集合中的元素
System.out.println(setOperations.members("setTest"));
- 删除数据
java
//获取集合中的元素
System.out.println(setOperations.members("setTest"));
//删除数据
setOperations.remove("setTest","set1");
System.out.println(setOperations.members("setTest"));
输出结果:
[set4, set3, set1, set2]
[set4, set3, set2]
- 获取集合的长度
java
//获取集合的长度
System.out.println(setOperations.size("setTest"));
输出结果:3
- 判断元素是否在集合中
java
//判断元素是否在集合中
System.out.println(setOperations.isMember("setTest","set2"));
输出结果:true
4.2.5操作hash opsForHash
- 创建opsForHash对象
java
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedisTemplate() {
//创建opsForHash对象
HashOperations hashOperations = redisTemplate.opsForHash();
}
- 添加数据
java
//使用opsForHash对象操作哈希结构 添加数据
hashOperations.put("users","name1","zhangsan");
hashOperations.put("users","name2","lisi");
hashOperations.put("users","name3","wangwu");
- 删除数据
java
//使用opsForHash对象操作哈希结构 删除数据
hashOperations.delete("users","name1");
- 获取数据
java
//使用opsForHash对象操作哈希结构 获取数据
System.out.println(hashOperations.get("users","name2"));
- 批量添加数据
java
//使用opsForHash对象操作哈希结构 批量添加数据
Map newMap = new HashMap();
newMap.put("map3","map3-3");
newMap.put("map5","map5-5");
hashOperations.putAll("users",newMap);
4.3StringRedisTemplate常用操作
java
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testRedisTemplate() {
//设置有效期 10分钟后过期
stringRedisTemplate.opsForValue().set("test","909",600000, TimeUnit.MILLISECONDS);
//60秒后,输出null
System.out.println(stringRedisTemplate.opsForValue().get("test")); //909
//获得键test的剩余有效期 单位:秒
System.out.println(stringRedisTemplate.getExpire("test"));//600
//删除键test
stringRedisTemplate.delete("test");
//向指定key中存放set集合
stringRedisTemplate.opsForSet().add("setTest","1","2","3");
//获取集合setTest的所有元素
System.out.println(stringRedisTemplate.opsForSet().members("setTest"));//[1, 2, 3]
//判断元素是否在Set集合中
System.out.println(stringRedisTemplate.opsForSet().isMember("setTest","1"));//true
//获取集合的长度
System.out.println(stringRedisTemplate.opsForSet().size("setTest"));//3
//添加数据到hash结构中
stringRedisTemplate.opsForHash().put("hashTest","name1","lisi");
stringRedisTemplate.opsForHash().put("hashTest","name2","wangwu");
stringRedisTemplate.opsForHash().put("hashTest","name3","zhangsan");
//判断hash结构中是否存在指定的key
System.out.println(stringRedisTemplate.hasKey("hashTest"));//true
}
5.StringRedisTemplate与RedisTemplate区别
- 两者的关系是StringRedisTemplate继承RedisTemplate
- 两者的数据是不共通的。StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
- 两者的使用的序列化类不同。RedisTemplate使用的是JdkSerializationRedisSerializer存入数据会将数据先序列化成字节数组然后在存入Redis数据库。 StringRedisTemplate使用的是 StringRedisSerializer