1、spring-data-redis项目简介
1.1 spring-data-redis项目的设计
Spring是通过spring-data-redis项目对Redis开发进行支持的。这里仅讨论Spring推荐使用的类库Jedis的使用。
Spring提供了一个RedisConnectionFactory接口,通过它可以生成一个RedisConnection接口对象,而RedisConnection接口对象是对Redis底层接口的封装。例如我们讨论的Jedis驱动,那么Spring就会提供RedisConnection接口的实现类JedisConnection去封装原有的Jedis对象。
在Spring中是通过RedisConnection接口操作Redis的,而RedisConnection则对原生的Jedis进行封装。要获取RedisConnection接口对象,是通过RedisConnectionFactory接口去生成的,所以第一步要配置的便是这个工厂了,而配置这个工厂主要是配置Redis的连接池,对于连接池可以限定其最大连接数、超时时间等属性。
我们在config包下创建名为RedisConfig的配置类,手动装配一个RedisConnectionFactory,具体代码如下:
package com.ccff.springboot.demo.chapter7.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.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import redis.clients.jedis.JedisPoolConfig;
/**
* Created by wangzhefeng01 on 2019/8/9.
*/
@Configuration
public class RedisConfig {
private RedisConnectionFactory connectionFactory = null;
@Bean(name = "redisConnectionFactory")
public RedisConnectionFactory initRedisConnectionFactory(){
if (this.connectionFactory != null){
return this.connectionFactory;
}
JedisPoolConfig poolConfig = new JedisPoolConfig();
//最大空闲数
poolConfig.setMaxIdle(50);
//最大连接数
poolConfig.setMaxTotal(100);
//最大等待时间毫秒数
poolConfig.setMaxWaitMillis(2000);
//创建Jedis连接工厂
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(poolConfig);
//获取单机的Redis配置
RedisStandaloneConfiguration configuration = connectionFactory.getStandaloneConfiguration();
configuration.setHostName("127.0.0.1");
configuration.setPort(6379);
configuration.setPassword("123456");
this.connectionFactory = connectionFactory;
return connectionFactory;
}
}
上面的代码通过一个连接池的配置创建了RedisConnectionFactory,通过它就能够创建RedisConnection接口对象。但是我们在使用一条连接时,要先从RedisConnectionFactory工厂获取,然后在使用完成后还要自己关闭它。Spring为了进一步简化开发,提供了RedisTemplate。
1.2 RedisTemplate
应该说RedisTemplate是使用最多的类,所以它是Spring操作Redis的重点内容。
首先它会自动从RedisConnectionFactory工厂中获取连接,然后执行对应的Redis命令,在最后还会关闭Redis连接。这些在RedisTemplate中都被封装了,所以并不需要开发者关注Redis的连接的闭合问题。
修改RedisConfig配置类,手动配置RedisTemplate,具体代码如下:
package com.ccff.springboot.demo.chapter7.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.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import redis.clients.jedis.JedisPoolConfig;
/**
* Created by wangzhefeng01 on 2019/8/9.
*/
@Configuration
public class RedisConfig {
private RedisConnectionFactory connectionFactory = null;
@Bean(name = "redisConnectionFactory")
public RedisConnectionFactory initRedisConnectionFactory(){
if (this.connectionFactory != null){
return this.connectionFactory;
}
JedisPoolConfig poolConfig = new JedisPoolConfig();
//最大空闲数
poolConfig.setMaxIdle(50);
//最大连接数
poolConfig.setMaxTotal(100);
//最大等待时间毫秒数
poolConfig.setMaxWaitMillis(2000);
//创建Jedis连接工厂
JedisConnectionFactory connectionFactory = new JedisConnectionFactory(poolConfig);
//获取单机的Redis配置
RedisStandaloneConfiguration configuration = connectionFactory.getStandaloneConfiguration();
configuration.setHostName("127.0.0.1");
configuration.setPort(6379);
configuration.setPassword("123456");
this.connectionFactory = connectionFactory;
return connectionFactory;
}
@Bean(name="redisTemplate")
public RedisTemplate<Object, Object> initRedisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(initRedisConnectionFactory());
return redisTemplate;
}
}
在手动装配RedisTemplate后,我们就可以使用其操作Redis了。在test文件夹下创建名为Test的测试类,具体代码如下所示:
import com.ccff.springboot.demo.chapter7.config.RedisConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
/**
* Created by wangzhefeng01 on 2019/8/9.
*/
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(RedisConfig.class);
RedisTemplate redisTemplate = context.getBean(RedisTemplate.class);
redisTemplate.opsForValue().set("key1","value1");
redisTemplate.opsForHash().put("hash","field","hvalue");
}
}
执行测试方法后,在Redis客户端通过命令“key *key1”进行查看,结果如下:
这里我们需要注意的是:Redis是一种基于字符串存储的NoSQL,而Java是基于对象的语言,对象是无法存储到Redis中的。不过,Java提供了序列化机制,只要类实现了java.io.Serializable接口,就代表类的对象能够进行序列化,通过将类对象进行序列化就能够得到二进制字符串,这样Redis就可以将这些类对象以字符串的形式进行存储。这也就是我们在上面的截图中看到的结果。同时,Java也可以将那些二进制字符串通过反序列化转为对象,通过这个原理,Spring提供了序列化器的机制,并且实现了几个序列化器。
1.3 序列化器
对于序列化器,Spring提供了RedisSerializer接口,它有两个方法。这两个方法,一个是serialize,它能够把那些可以序列化的对象转换为二进制字符串;另一个是deserialize,它能够通过反序列化把二进制字符串转换为Java对象。
在Spring中,最常用的两个序列化器是StringRedisSerializer和JdkSerializationRedisSerializer,其中JdkSerializationRedisSerializer是RedisTemplate默认的序列化器。
RedisTemplate提供了下表所示的几个可以配置的属性
属性 | 描述 | 备注 |
---|---|---|
defaultSerializer | 默认序列化器 | 如果没有设置,则使用JdkSerializationRedisSerializer |
keySerializer | Redis键序列化器 | 如果没有设置,则使用默认序列化器 |
valueSerializer | Redis值序列化器 | 如果没有设置,则使用默认序列化器 |
hashKeySerializer | Redis散列结构field序列化器 | 如果没有设置,则使用默认序列化器 |
hashValueSerializer | Redis散列结构value序列化器 | 如果没有设置,则使用默认序列化器 |
stringSerializer | 字符串序列化器 | RedisTemplate自动赋值为StringSerializer对象 |
为了使我们在Redis客户端显示的结果变为可读的字符串,因此需要修改在RedisConfig配置类中对RedisTemplate的装配。具体修改如下:
@Bean(name="redisTemplate")
public RedisTemplate<Object, Object> initRedisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(initRedisConnectionFactory());
RedisSerializer<String> stringRedisSerializer = redisTemplate.getStringSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(stringRedisSerializer);
return redisTemplate;
}
通过上面的代码,主动将Redis的键和散列结构的field和value均采用了字符串序列化器,这样把它们转换出来时就采用字符串了。再次执行测试类后,在Redis的客户端中进行查看,结果如下:
1.4 Spring对Redis数据类型操作的封装
Redis能够支持7种类型的数据结构,这7种类型是:
- 字符串
- 散列
- 列表(链表)
- 集合
- 有序集合
- 基数
- 地理位置
为此,Spring针对每一种数据结构的操作都提供了对应的操作接口
操作接口 | 功能 | 备注 |
---|---|---|
GeoOperations | 地理位置操作接口 | 使用不多 |
HashOperations | 散列操作接口 | - |
HyperLogLogOperations | 基数操作接口 | 使用不多 |
ListOperations | 列表(链表)操作接口 | - |
SetOperations | 集合操作接口 | - |
ValueOperations | 字符串操作接口 | - |
ZSetOperations | 有序集合操作接口 | - |
而这些操作接口都可以通过RedisTemplate得到,得到的方法也很简单:
//获取地理位置操作接口
redisTemplate.opsForGeo();
//获取散列操作操作接口
redisTemplate.opsForHash();
//获取基数操作操作接口
redisTemplate.opsForHyperLogLog();
//获取列表(链表)操作接口
redisTemplate.opsForList();
//获取集合操作接口
redisTemplate.opsForSet();
//获取字符串操作接口
red