05-Java操作Redis
五、Java操作Redis
- Redis 的 Java 客户端很多,官方推荐的有三种:
- Jedis
- Lettuce
- Redisson
- Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis
5.1、Jedis
-
Jedis是Redis的Java版本的客户端实现
-
相关maven坐标
-
<dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
-
-
使用Jedis操作Redis的步骤
- ①、获取连接
- ②、执行操作
- ③、关闭连接
-
示例代码
-
package com.coolman; import org.junit.Test; import redis.clients.jedis.Jedis; public class JedisTest { @Test public void jedisTest() { // 1. 连接redis // 创建一个Jedis对象连接Redis数据库 Jedis jedis = new Jedis("127.0.0.1", 6379); // 2. 执行操作 // 存储数据 jedis.set("name", "coolman"); // 获取数据 System.out.println(jedis.get("name")); // 3. 关闭连接 jedis.close(); } }
-
5.2、Spring Data Redis
-
Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作
-
官网
-
相关maven坐标
-
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.4.8</version> </dependency>
-
SpringBoot也提供了对应的starter
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
-
-
Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对 Jedis 客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:
- ValueOperations:简单K-V操作
- HashOperations:针对hash类型的数据操作
- ListOperations:针对list类型的数据操作
- SetOperations:set类型数据操作
- ZSetOperations:zset类型数据操作
提前初始化一个SpringBoot项目,其中的配置文件信息如下
spring: redis: host: 127.0.0.1 port: 6379 # password: 有密码你才写 database: 0 #redis默认有16个数据库, 操作的数据库是哪个 jedis: pool: max-active: 10 #最大链接数,连接池中最多有10个 max-idle: 5 # 最大空闲数 , 618你们公司业务比较繁忙,招聘10个人, 3个人有活干,空闲了7个人 min-idle: 1 #最小空闲数 618到来之前,发现只有1个人没活干, 赶紧去招聘。 #举个例子: 连接池初始化3个链接, 客户拿走2个链接,空闲1个,达到最小的空闲数,必须马上增加 max-wait: 1ms #连接池最大阻塞等待时间
解释说明
- spring.redis.database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15
- 可以通过修改Redis配置文件来指定数据库的数量
-
前置步骤
-
pringdata_redis默认帮我们创建的RedisTemplate对象是使用jdk的序列号器帮我们键与值存储到redis中,而jdk的序列号器对键与值是采用二进制的方式存储的,所以我们会看到乱码的情况。如果我们需要看得懂,那么需要修改redistemplate使用的序列号器才行。
-
提供配置类如下所示
-
package com.coolman.config; 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.StringRedisSerializer; @Configuration public class MyRedisAutoConfig { @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); template.setKeySerializer(new StringRedisSerializer()); //key的序列号器 template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); //值序列号器 return template; } }
-
注意事项
- 当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象,但是默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别
-
-
导入相关依赖
-
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.coolman</groupId> <artifactId>Redis-Test</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <parent> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.5.6</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.11.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.11.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.4.5</version> </plugin> </plugins> </build> </project>
-
-
提供测试类
-
package com.coolman; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; public class SpringDataRedisTest { @Autowired private RedisTemplate<String, String > redisTemplate; }
-
5.3.1、操作字符串类型数据
-
测试代码
-
@Test public void stringTest() { // 1. 获取操作字符串类型的对象 ValueOperations<String, String> valueOperations = redisTemplate.opsForValue(); // 2. 执行操作字符串命令 // 存储 valueOperations.set("name", "嘿嘿Boy"); // 获取 System.out.println(valueOperations.get("name")); // 设置过期时间(一分钟) valueOperations.set("age", "18", 1, TimeUnit.MINUTES); // 如果不存在key则添加,否则不添加 valueOperations.setIfAbsent("name", "嘿嘿NewBoy"); System.out.println(valueOperations.get("name")); }
-
-
-
输出结果
5.3.2、操作哈希类型数据
-
测试代码
-
@Test public void hashTest() { //1. 获取hash类型客户端 HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash(); // 2. 执行hash操作命令 // 存储 hashOperations.put("coolman", "age", "18"); hashOperations.put("coolman", "name", "you konw what i mean"); hashOperations.put("coolman", "sex", "superBoy"); // 取 System.out.println(hashOperations.get("coolman", "name")); // 获取所有hash_key Set<Object> hashSet = hashOperations.keys("coolman"); System.out.println("所有的hash_key为:"); hashSet.forEach(System.out::println); // 获取所有的value List<Object> values = hashOperations.values("coolman"); System.out.println("所有的value为:"); values.forEach(System.out::println); }
-
-
输出结果
5.3.3、操作列表类型数据
-
测试代码
-
@Test public void listTest() { // 1. 获取list类型客户端 ListOperations<String, String> listOperations = redisTemplate.opsForList(); // 2. 执行list操作命令 listOperations.leftPushAll("list", "s1", "s2", "s3"); // 3. 获取所有元素 System.out.println(listOperations.range("list", 0, -1)); // 4. 获取元素个数 System.out.println(listOperations.size("list")); }
-
-
输出结果
5.3.4、操作集合类型数据
-
测试代码
-
@Test public void setTest() { // 1. 获取set集合客户端 SetOperations<String, String> setOperations = redisTemplate.opsForSet(); // 2. 执行set操作命令 // 存储 setOperations.add("wife_set", "林志玲", "刘亦菲", "莫妮卡", "dream_wife"); // 获取 Set<String> wifeSet = setOperations.members("wife_set"); wifeSet.forEach(System.out::println); // 删除 setOperations.remove("wife_set", "林志玲"); System.out.println("删除后内容如下所示:"); Set<String> wifeSetDel = setOperations.members("wife_set"); wifeSetDel.forEach(System.out::println); }
-
-
输出结果
5.3.5、操作有序集合类型数据
-
测试代码
-
@Test public void orderSetTest() { // 1. 获取有序集合类型客户端 ZSetOperations<String, String> zSetOperations = redisTemplate.opsForZSet(); // 2. 执行操作 // 添加 zSetOperations.add("wife_z_set", "林志玲", 60); zSetOperations.add("wife_z_set", "刘亦菲", 98); zSetOperations.add("wife_z_set", "莫妮卡", 97); zSetOperations.add("wife_z_set", "dream_wife", 100); // 获取 Set<String> wifeZSet = zSetOperations.range("wife_z_set", 0, -1); System.out.println("-------------------------------"); wifeZSet.forEach(System.out::println); // 修改 zSetOperations.incrementScore("wife_z_set", "刘亦菲", 100); System.out.println("-------------------------------"); zSetOperations.range("wife_z_set", 0, -1).forEach(System.out::println); }
-
-
输出结果
5.3.6、通用操作
-
测试代码
-
@Test public void commonTest() { // 1. 获取所有键 System.out.println(redisTemplate.keys("*")); // 2. 判断有无该键 System.out.println("redisTemplate.hasKey(\"wife_set\") = " + redisTemplate.hasKey("wife_set")); System.out.println("redisTemplate.hasKey(\"wife\") = " + redisTemplate.hasKey("wife")); // 3. 获取键的类型 System.out.println(redisTemplate.type("wife_z_set")); // 4. 删除键 redisTemplate.delete("wife_z_set"); System.out.println(redisTemplate.keys("*")); }
-
-
输出结果