Redis与Spring Data Redis
本文共 23,473 字,预计阅读时间 78 分钟
1.Redis概述
1.1介绍
Redis是一个开源的使用ANSIC语言编写、支持网络、可基于内存 亦可持久化的日志型、Key-Value型的高性能数据库。
1.2特性
1.Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
2.Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
3.Redis支持数据的备份,是单线程的。
2.Redis下载与安装
2.1下载
linux版下载地址如下:
1 | https: //redis.io/download |
下载的文件是二进制的压缩包,适用于linux。在windows安装redis见2.3.
2.2在linux安装redis
把下载的压缩包上传到linux中,这里以centos7为例:
1)解压
1 | tar -xzvf redis- 4.0 . 8 .tar.gz |
2)安装
1 2 3 4 | cd redis- 4.0 . 8 make cd src make install PREFIX=/usr/local/redis |
3)移动配置文件到安装目录
1 2 3 | mkdir /usr/local/redis/etc cd .. mv redis.conf /usr/local/redis/etc |
4)首次启动redis
1 2 | cd /usr/local/redis/bin ./redis-server |
看到下图说明安装成功
后期可使用下面的命令启动,使用配置文件启动redis
1 | /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf |
5)设置redis后台启动
1 | vi /usr/local/redis/etc/redis.conf |
将daemonize no 改成daemonize yes,保存退出。
6)将redis加入到开机启动
1 | vi /etc/rc.local |
在里面添加
1 | /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf |
7)关闭redis服务
1 | pkill redis |
8)redis客户端连接测试(此时已默认开启了redis)
1 | /usr/local/redis/bin/redis-cli |
如果设置了密码,就要使用密码登录
1 | /usr/local/redis/bin/redis-cli -h ip地址 -p 6379 -a 密码 |
设置密码的方式
在配置文件redis.conf中找到这行代码
1 | # requirepass foobared |
取消注释,后面设置密码,这是设置为1234。然后关闭服务再开启(关闭/开启见上)
1 | requirepass 1234 |
9)设置允许外网访问
在配置文件redis.conf中把bind开始的代码注释掉,如下,同样需要重启服务:
1 | #bind 127.0 . 0.1 |
2.3在windows安装redis
2.3.1下载与安装
下载网站:https://github.com/microsoftarchive/redis/releases。下载需要版本的msi文件。
下载后傻瓜式安装即可。
2.3.2使用
1)在安装目录下打开Redis服务配置文件,找到# requirepass foobared,在下面写requirepass 1234,用来配置密码
2)点击“开始”>右击“计算机”>选择“管理”。在左侧栏中依次找到并点击“计算机管理(本地)”>服务和应用程序>服务。再在右侧找到Redis名称的服务,查看启动情况。如未启动,则手动启动之。正常情况下,服务应该正常启动并运行了。
3)在redis安装目录,打开cmd窗口,输入redis-cli,可以看到连接上了redis,如图
4)再继续输入auth 1234验证密码,显示OK就可以进入redis,来操作redis了。
2.4可视化工具安装
当然也有对应的工具来连接redis数据库,这里使用Redis Desktop Manager。此工具直接安装在windows系统。
1)下载
官网下载:http://redisdesktop.com/download
网盘下载:链接:https://pan.baidu.com/s/1odEEq9O137I6pHuFZ0reCg 提取码:1235
2)安装
点击exe进行傻瓜式安装。安装完成会在桌面生成一个快捷方式。
3)使用
打开之后,点击左下角的连接redis服务来连接redis,连接之后就可以看到里面的数据。
3.redis基本指令
3.1查看所有的key值keys
1 | keys * |
3.2添加值set
1 2 3 | set key value //示例 set name zhangsan |
3.3获取key值get
1 2 3 | get key //示例 get name |
3.4判断key是否存在exists
只要指定的key中有一个存在就返回1。
1 2 3 | exists key //示例 exists name age |
3.5对key设置失效时间expire
当对key设置失效时间后,过了此时间,key就会自动删除。单位是秒。
1 2 3 | expire key //示例,10s失效 expire name 10 |
pexpire和expire类型,只不过其单位是毫秒。
3.6获取key的剩余生存时间ttl
单位是秒,当key不在时返回-2,当key存在且没有设置剩余时间时返回-1。
1 2 3 | ttl key //示例 ttl name |
pttl同ttl,返回值是毫秒。
3.7随机返回key值randomkey
随机返回一个key,但不删除
1 2 3 | randomkey //示例 randomkey |
3.8修改key值rename
1 2 3 | rename key newkey //示例 rename name name1 |
3.9获取值的类型type
1 2 3 | type key //示例 type name |
4.不同类型的get和set指令
4.1String类型
1 2 3 4 | 设置 set name zhangsan 获取 get name |
4.2List类型
有序,可重复
1 2 3 4 5 6 7 8 9 10 11 12 | 从头部添加 lpush userLists zhangsan lisi wangwu zhaoliu 遍历list,可以指定起止索引 lrange userLists 0 -1 从尾部添加 rpush userList li123 hu123 zhao456 删除第一个元素 lpop userList 删除最后一个元素 rpop userList 获取元素的个数 llen userList |
4.3Set类型
无序,不能重复
1 2 3 4 5 6 7 8 9 10 | 添加元素 sadd arr 1 3 4 7 4 3 6 显示所有的元素 smembers arr 返回元素的个数 scard arr 随机删除一个元素 spop arr 删除指定元素 srem arr 4 |
4.4Zset类型
不可重复,元素根据分数有序
1 2 3 4 5 6 7 8 9 10 11 12 | 添加元素,指定每个元素的分值 zadd arr 10 zhangsan 9 lisi 12 wangwu 6 zhaoliu 查看所有元素,升序 zrange arr 0 -1 查看所有元素,降序并显示分数 zrevrange arr 0 -1 withscores 返回元素的个数 zcard arr 查看排名,降序的排名 zrank arr zhangsan 删除指定元素 zrem arr zhangsan |
4.5Hash类型
value是一个map类型。map的字段又分别是field和value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 添加值 hset maps name zhangsan 获取值 hget maps name 遍历键值对 hgetall maps 删除某一个键值对 hdel maps name 判断key是否存在,不存在返回0,存在返回1 hexist maps name 获取所有的key hkeys maps 获取所有的value hvals maps |
5.redis持久化机制
把内存中的数据存入磁盘,这个就是持久化的过程。
5.1快照
将某一时刻的所有数据都写入硬盘中,保存的文件是以.rdb形式结尾的文件,这种方式也称之为RDB方式,是默认开启持久化的方式。
5.1.1快照生成方式
1)客户端方式
第一种方式:bgsave指令
客户端使用BGSAVE命令来创建一个快照,当接收到客户端的BGSAVE命令时, redis会调用fork1来创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求。
第二种方式:save指令
客户端也可以使用SAVE命令来创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令,此时在生成快照之前,redis服务处于阻塞状态。
5.2AOF
这种方式可以将所有客户端执行的写命令记录到日志文件中,AOF持久化会将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化,因此只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件的记录的数据集。
开启aof方法:
vi /usr/local/redis/etc/redis.conf
把appendonly no改为yes
6.java操作redis
6.1环境准备
1)新建一个maven的java项目
2)导入坐标
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency>
3)创建jedis对象测试连接
public class Test { public static void main(String[] args) { //创建jedis客户端对象 Jedis jedis = new Jedis("192.168.159.129"); //指定密码 jedis.auth("123456"); //获取所有的key Set<String> keys = jedis.keys("*"); System.out.println(keys); //释放资源 jedis.close(); } }
直接运行main函数,可以打印出所有的key值,说明连接成功。
6.2基本测试
创建一个测试类,配置redis服务,然后所有的测试方法就在这个类中进行。
public class RedisTest { private Jedis jedis; /** * 运行之前执行,开始连接 */ @Before public void before(){ jedis=new Jedis("192.168.159.129"); jedis.auth("123456"); } /** * 运行之后执行,关闭连接 */ @After public void after(){ jedis.close(); } }
6.2.1string类型测试
@Test public void stringSet(){ jedis.set("name","hello world"); } @Test public void stringGet(){ String name = jedis.get("name"); System.out.println(name); }
6.2.2list类型测试
@Test public void listSet(){ jedis.lpush("lists","zhangsan","lisi","王五"); jedis.rpush("lists","李敏","李四","赵丽"); } @Test public void listGet(){ List<String> lists = jedis.lrange("lists", 0, -1); System.out.println(lists); }
6.2.3set类型上测试
@Test public void setSet(){ jedis.sadd("set","123","456","789","456","666"); } @Test public void setGet(){ Set<String> set = jedis.smembers("set"); System.out.println(set); }
6.2.4zset类型测试
@Test public void zsetSet(){ jedis.zadd("zset",10,"张三"); jedis.zadd("zset",12,"李四"); jedis.zadd("zset",8,"张虎"); } @Test public void zsetGet(){ Set<String> set = jedis.zrange("zset",0,-1); System.out.println(set); }
6.2.5hash类型测试
@Test public void hashSet(){ jedis.hset("maps","name","张三"); jedis.hset("maps","age","20"); jedis.hset("maps","sex","男"); } @Test public void hashGet(){ Map<String, String> maps = jedis.hgetAll("maps"); System.out.println(maps); }
7.springboot操作redis
7.1环境准备
1)创建一个springboot的项目
2)导入坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
3)配置数据源
#配置redis服务 spring: redis: #配置redis的编号,redis有16个database,0~15 database: 0 #配置主机地址 host: 192.168.159.129 #配置redis端口号,默认是6379 port: 6379 #配置redis登录密码 password: 123456 #配置连接池信息 jedis: pool: #配置最大连接数 max-active: 8 #配置最大空闲连接数 max-idle: 8 #配置最大阻塞等待时间 max-wait: -1ms #配置最小空闲连接数 min-idle: 0
7.2基本测试
在测试类中注入对象
//当存储的值是string类型时使用 @Autowired private StringRedisTemplate stringRedisTemplate; //当存储的值是对象类型时使用 @Autowired private RedisTemplate redisTemplate;
7.2.1key的基本操作
//设值字段的超时时间,单位是秒,超过时间后redis会自动删除 @Test public void keyTimeOut(){ stringRedisTemplate.expire("name",10, TimeUnit.SECONDS); } //判断key存在 @Test public void keyIsExists(){ Boolean exists = stringRedisTemplate.hasKey("name"); System.out.println(exists); } //删除key @Test public void keyDelete(){ stringRedisTemplate.delete("name"); }
7.2.2string类型基本操作
//string类型的操作,使用opsForValue @Test public void stringSet(){ stringRedisTemplate.opsForValue().set("name","张三"); } @Test public void stringGet(){ String s = stringRedisTemplate.opsForValue().get("name"); System.out.println(s); }
7.2.3list类型基本操作
//list类型的操作,使用opsForList @Test public void listSet(){ stringRedisTemplate.opsForList().leftPush("lists","zhangsan"); stringRedisTemplate.opsForList().leftPushAll("lists","李敏","李四","赵丽"); } @Test public void listGet(){ List<String> lists = stringRedisTemplate.opsForList().range("lists",0,-1); System.out.println(lists); }
7.2.4set类型基本操作
//set类型的操作,使用opsForSet @Test public void setSet(){ stringRedisTemplate.opsForSet().add("set","123","456","789","456","666","999","啧啧啧"); } @Test public void setGet(){ Set<String> set = stringRedisTemplate.opsForSet().members("set"); System.out.println(set); }
7.2.5zset类型基本操作
//zset类型的操作,使用opsForZSet @Test public void zsetSet(){ stringRedisTemplate.opsForZSet().add("zset","张三",10); stringRedisTemplate.opsForZSet().add("zset","李四",20); stringRedisTemplate.opsForZSet().add("zset","王五",30); } @Test public void zsetGet(){ Set<String> set = stringRedisTemplate.opsForZSet().range("zset",0,-1); System.out.println(set); }
7.2.6hash类型基本操作
//hash类型的操作,使用opsForHash @Test public void hashSet(){ stringRedisTemplate.opsForHash().put("maps","name","张三"); stringRedisTemplate.opsForHash().put("maps","age","20"); stringRedisTemplate.opsForHash().put("maps","sex","男"); } @Test public void hashGet(){ Map<Object, Object> maps = stringRedisTemplate.opsForHash().entries("maps"); System.out.println(maps); }
7.3redisTemplate与stringRedisTemplate的区别
1)两者数据各自存,各自取,数据不互通。
2)序列化策略不同。RedisTemplate采用JDK的序列化策略,StringRedisTemplate采用String的序列化策略。
3)存储数据类型不同。StringRedisTemplate的key和value都是stringt类型,RedisTemplate的key和value都是object类型。
7.4定义常用工具类RedisUtil
以string类型为例,其他雷同。
package com.zys.redisdemo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * @author zhongyushi * @date 2020/9/12 16:30:30 * @dec redis工具类 */ @Component public class RedisUtil { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate redisTemplate; /** * string类型 */ //删除key public void deleteKey(String key) { stringRedisTemplate.delete(key); } //判断key存在 public boolean keyIsExists(String key) { return stringRedisTemplate.hasKey(key); } //设置key失效时间,以秒为单位 public void setKeyTimeOut(String key, long second) { stringRedisTemplate.expire(key, second, TimeUnit.SECONDS); } //设置值 public void setValue(String key, String val) { stringRedisTemplate.opsForValue().set(key, val); } //获取值 public String getValue(String key) { return stringRedisTemplate.opsForValue().get(key); } /** * object类型 */ //存入对象 public void setObject(String key,Object obj){ redisTemplate.opsForValue().set(key,obj); } //获取对象 public Object getObject(String key){ return redisTemplate.opsForValue().get(key); } //删除对象 public void delObject(String key){ redisTemplate.delete(key); } //设置对象过期时间 public void setObjectTimeOut(String key,long second){ redisTemplate.expire(key,second,TimeUnit.SECONDS); } //判断对象是否存在 public boolean objectIsExists(String key) { return redisTemplate.hasKey(key); } }
8.redis缓存
虽然mybatis有自己的缓存,但是存在于应用服务器,那么使用redis做缓存是当前的趋势。
源码:https://github.com/zhongyushi-git/redis-demo.git
8.1项目准备
首先创建一个springboot的项目,包含mysql、mybatis和redis,且有基本的数据访问接口,sql脚本在项目根目录下。
注意:要实现缓存,每个实体对象必须实现序列化接口。
8.2缓存的基本实现
1)获取spring创建的工厂
package com.zys.redisdemo.util; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Configuration; /** * @author zhongyushi * @date 2020/9/16 0016 * @dec 获取spring创建的工厂 */ @Configuration public class ApplicationContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; //把非spring创建好的工厂赋值给applicationContext,applicationContext在这个应用中是唯一的 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } //此创建好工厂后再获取对象 public static Object getBean(String beanName){ return applicationContext.getBean(beanName); } }
此类的作用就是把非spring创建好的工厂赋值给applicationContext,然后spring再根据类名去获取对应的类。
2)redis缓存类,实现Cache
package com.zys.redisdemo.cache; import com.zys.redisdemo.util.ApplicationContextUtil; import org.apache.ibatis.cache.Cache; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.util.concurrent.locks.ReadWriteLock; /** * @author zhongyushi * @date 2020/9/16 0016 * @dec 配置redis缓存,使用redis作为缓存服务器,减轻mysql服务器的访问压力 */ public class RedisCache implements Cache { //是mybatis必须要求的,必写。此id是xml中的namespace的值 private final String id; public RedisCache(String id){ this.id=id; } //返回cache的唯一名称 @Override public String getId() { return this.id; } //缓存存值 @Override public void putObject(Object key, Object value) { //id是namespace的值,key是方法名,value是查询的结果 getRedisTemplate().opsForHash().put(id, key.toString(), value); } //缓存取值 @Override public Object getObject(Object key) { return getRedisTemplate().opsForHash().get(id, key.toString()); } //mybatis保留方法 @Override public Object removeObject(Object key) { return null; } //清空缓存,在增删改时会自动调用 @Override public void clear() { getRedisTemplate().delete(id); } //缓存的数量 @Override public int getSize() { return getRedisTemplate().opsForHash().size(id).intValue(); } @Override public ReadWriteLock getReadWriteLock() { return null; } //获取RedisTemplate,不能通过注入的方式,原因是此类是由mybatis实例化的 private RedisTemplate getRedisTemplate(){ //从上下文中获取redisTemplate RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate"); //设置key是string类型的序列 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置hashKey是string类型的序列 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); return redisTemplate; } }
在这个类中,分别重写了缓存设置、获取和删除的方法,把数据放到redis中。但是在此类中无法直接注入RedisTemplate,此类是由mybatis实例化的,不是由工厂实例化的。但是可以通过applicationContext来获取。
3)开启缓存
在xml中使用mybatis来开启缓存,指定为自定义的类型
<!--使用mybatis开启redis缓存--> <cache type="com.zys.redisdemo.cache.RedisCache"/>
4)测试
启动项目,使用postman对接口进行测试。结果显示,对于两个查询的操作,第一次查询会从数据库获取,多次调用时就从redis中获取。对于删除操作,会把对应的缓存数据清除,实际上修改和添加也是一样。即增删改都会清空缓存,这里以删除为例,是mybatis的缓存机制的体现。
8.3缓存的问题(共享缓存)
在上一小节的实例中,简单的数据都可以通过redis进行缓存,对应的更新更新缓存只在单个表中,不会影响其他的表。但是如果多个表具有关联关系时,还使用这种方式,就会出现数据无法更新的问题。
在xml中使用cache标签,那么其缓存是相互独立的,对于多表关联时,可以使用cache-ref标签。
比如新建一个ErpMapper.xml,在其中使用此标签
<!--多表关联关系的缓存处理--> <cache-ref namespace="com.zys.redisdemo.dao.UserDao"/>
在ErpMapper中指定了namespace是UserDao,那么不管是User表的数据发生变化还是Erp表数据发生变化,都会删除User的缓存数据,从而及时的更新用户数据。
8.4缓存优化
在查看缓存的时候,发现存入的hash的key很长,是可以进行优化的,使用md5对数据进行简化,会生成一个32位的16进制字符串。
1)在RedisCache类添加加密的方法
//给定的字符串进行md5加密,转为32位的16进制 private String md5AsHex(String key){ return DigestUtils.md5DigestAsHex(key.getBytes()); }
2)然后对key进行加密,见源码。
8.5常见的面试题
8.5.1缓存穿透(击穿)
定义:客户端查询了一个数据库中不存在的记录,导致缓存不能使用。
解决:mybatis的cache就解决了此问题,即使查询的数据不存在,也会放到缓存中,只不过value为null而已。
8.5.2缓存雪崩
定义:在系统运行的某一时刻,突然系统中的所有缓存全部失效,恰好在这一时刻有大量的请求,导致所有的缓存无法使用。以至于大量的请求去请求数据库,让数据库阻塞或挂起。
解决:
1)缓存失效的原因之一就是对缓存设置了失效的时间,那么这样的缓存可以设置永久生效,不设置缓存失效时间。
2)针对不同的业务做不同的超时时间。
9.redis的session共享
9.1什么是session共享
session共享简单的来说就是把用户登录后的session根据用户的唯一主键放到redis里面,用户在访问分布的其他系统时先去redis中查看是否有这个用户的session信息,有的话就不用再次登录,没有就需要登录。它是基于应用的session共享。
9.2session共享的应用
1)添加session依赖
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
2)在controller中的存储和获取session
package com.zys.redisdemo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession; @RestController public class RedisController { @GetMapping("/save") public String save(String name, HttpSession session) { //向session中存储数据 session.setAttribute("name", name); return name; } @GetMapping("/get") public String get(HttpSession session) { //从session中h获取数据 return "session中的数据" + session.getAttribute("name"); } }
3)把这个项目打包,然后部署到本地的两个tomcat上,这里端口就用8080和8081。
4)测试。浏览器输入http://localhost:8080/redis/save?name=123,对session的name设置值,然后再输入http://localhost:8081/redis/save?get使用另一个服务器来获取存入的值,发现是可以取到的。实际上,在存入的时候,会把session中的数据存储到redis中,取的时候是去redis获取的,这就是redis的session共享,对特定的数据共享非常方便。
注意:使用redis的session共享时,只要session的内容发送变化,就要及时更新redis的内容。
10.Spring Data Redis
10.1定义
Spring-data-redis是spring大家族的一部分,提供了在srping应用中通过简单的配置访问redis服务,对reids底层开发包(Jedis, JRedis, and RJC)进行了高度封装,RedisTemplate提供了redis各种操作、异常处理及序列化,支持发布订阅。
spring-data-redis针对jedis提供了如下功能:
1)连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2)针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,如下:
1 2 3 4 5 | boundValueOps: string 简单K-V操作 boundSetOps: set 类型数据操作 boundZSetOps:zset类型数据操作 boundHashOps:针对map类型的数据操作 boundListOps:针对list类型的数据操作 |
10.2基本用法
10.2.1环境准备
这里就直接在redis的项目中进行说明。
1)导入坐标,如果没有导入请先导入,如果已经导入此步可省略。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
不难发现,此依赖和springboot整合redis的依赖是一样的,这也就证实了Spring-data-redis是对redis的封装,只能使用在springboot的项目中,不能用在spring的项目里面。
新建一个测试类,注入对象
//当存储的值是string类型时使用 @Autowired private StringRedisTemplate stringRedisTemplate; //当存储的值是对象类型时使用 @Autowired private RedisTemplate redisTemplate;
10.2.2key的基本操作
key的基本操作和上面一样,再辞略。
10.2.3string类型基本操作
//string类型的操作,使用boundValueOps @Test public void stringSet(){ stringRedisTemplate.boundValueOps("name").set("张三"); } @Test public void stringGet(){ String s = stringRedisTemplate.boundValueOps("name").get(); System.out.println(s); }
10.2.4list类型基本操作
//list类型的操作,使用boundListOps @Test public void listSet(){ stringRedisTemplate.boundListOps("lists").leftPush("zhangsan"); stringRedisTemplate.boundListOps("lists").leftPushAll("李敏","李四","赵丽"); } @Test public void listGet(){ List<String> lists = stringRedisTemplate.boundListOps("lists").range(0,-1); System.out.println(lists); }
10.2.5set类型基本操作
//set类型的操作,使用boundSetOps @Test public void setSet(){ stringRedisTemplate.boundSetOps("set").add("123","456","789","456","666","999","啧啧啧"); } @Test public void setGet(){ Set<String> set = stringRedisTemplate.boundSetOps("set").members(); System.out.println(set); }
10.2.6zset类型基本操作
//zset类型的操作,使用boundZSetOps @Test public void zsetSet(){ stringRedisTemplate.boundZSetOps("zset").add("张三",10); stringRedisTemplate.boundZSetOps("zset").add("李四",20); stringRedisTemplate.boundZSetOps("zset").add("王五",30); } @Test public void zsetGet(){ Set<String> set = stringRedisTemplate.boundZSetOps("zset").range(0,-1); System.out.println(set); }
10.2.7hash类型基本操作
//hash类型的操作,使用boundHashOps @Test public void hashSet(){ stringRedisTemplate.boundHashOps("maps").put("name","张三"); stringRedisTemplate.boundHashOps("maps").put("age","20"); stringRedisTemplate.boundHashOps("maps").put("sex","男"); } @Test public void hashGet(){ Map<Object, Object> maps = stringRedisTemplate.boundHashOps("maps").entries(); System.out.println(maps); }
10.3工具类改写
package com.zys.redisdemo.util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; /** * @author zhongyushi * @date 2020/9/12 16:30:30 * @dec redis工具类 */ @Component public class RedisUtil { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private RedisTemplate redisTemplate; /** * string类型 */ //删除key public void deleteKey(String key) { stringRedisTemplate.delete(key); } //判断key存在 public boolean keyIsExists(String key) { return stringRedisTemplate.hasKey(key); } //设置key失效时间,以秒为单位 public void setKeyTimeOut(String key, long second) { stringRedisTemplate.expire(key, second, TimeUnit.SECONDS); } //设置值 public void setValue(String key, String val) { stringRedisTemplate.boundValueOps(key).set(val); } //获取值 public String getValue(String key) { return stringRedisTemplate.boundValueOps(key).get(); } /** * object类型 */ //存入对象 public void setObject(String key,Object obj){ getRedisTemplate().boundValueOps(key).set(obj); } //获取对象 public Object getObject(String key){ return getRedisTemplate().boundValueOps(key).get(); } //删除对象 public void delObject(String key){ getRedisTemplate().delete(key); } //设置对象过期时间 public void setObjectTimeOut(String key,long second){ getRedisTemplate().expire(key,second,TimeUnit.SECONDS); } //判断对象是否存在 public boolean objectIsExists(String key) { return getRedisTemplate().hasKey(key); } //获取RedisTemplate,把key进行string序列化,那么在库中就显示的原始的key值,否则就是16进制的值不方便。 private RedisTemplate getRedisTemplate(){ //设置key是string类型的序列 redisTemplate.setKeySerializer(new StringRedisSerializer()); //设置hashKey是string类型的序列 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); return redisTemplate; } }
此工具类进行对redisTemplate进行了优化,设置key序列化,以便查看库时方便。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!