除了关系型数据库之外,现在还有一种 NoSQL 数据库非常流行,而 Spring 自然也没有放过对它的支持。
NoSQL 数据库有很多种,如:
- MongoDBGenericJackson2JsonRedisSerializer
- Redis
- Membase
我们这里就重点讲解 Redis 。
注:这里前置认为各位对 Redis 已经有所了解并且安装好环境,如果对 Redis 还不了解的同学可以先移步到 Redis学习总结系列。
导入依赖
<!-- Redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
连接到 Redis
Redis 客户端有很多种 **Spring Data Redis ** 也对这些客户端实现分别提供了连接工厂:
- JedisConnectionFactory
- JredisConnectionFactory
- LettuceConnectionFactory
- SrpConnectionFactory
具体选择哪个连接工厂取决于项目需求,我们这里以 JedisConnectionFactory 为例。
从 Spring Data Redis 2.0 开始已经不推荐直接显式配置连接信息了,一方面为了使配置信息与建立连接工厂解耦,另一方面抽象出 Standalone,Sentinel 和 RedisCluster 三种模式的环境配置类和一个统一的 jedis 客户端连接配置类(用于配置连接池和SSL连接),使得我们可以更加灵活方便根据实际业务场景需要来配置连接信息。
不使用连接池
@Configuration
public class RedisConfiguration {
@Bean
public RedisStandaloneConfiguration redisStandaloneConfiguration() {
RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration();
// 设置主机地址
redisStandaloneConfiguration.setHostName("localhost");
// 设置默认数据库
redisStandaloneConfiguration.setDatabase(0);
// 设置密码
// redisStandaloneConfiguration.setPassword(RedisPassword.of("123456"));
// 设置端口
redisStandaloneConfiguration.setPort(6379);
return redisStandaloneConfiguration;
}
@Bean
public RedisConnectionFactory redisConnectionFactory(RedisStandaloneConfiguration redisStandaloneConfiguration) {
return new JedisConnectionFactory(redisStandaloneConfiguration);
}
}
使用连接池单机版
@Configuration
public class RedisConfiguration {
/**
* 连接池配置信息
*
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
//最大连接数
jedisPoolConfig.setMaxTotal(100);
//最小空闲连接数
jedisPoolConfig.setMinIdle(20);
//当池内没有可用的连接时,最大等待时间
jedisPoolConfig.setMaxWaitMillis(10000);
return jedisPoolConfig;
}
@Bean
public JedisClientConfiguration jedisClientConfiguration(JedisPoolConfig jedisPoolConfig){
// 获得默认的连接池构造器
JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb =
(JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration.builder();
// 指定 jedisPoolConifig 来修改默认的连接池构造器
jpcb.poolConfig(jedisPoolConfig);
// 通过构造器来构造 jedis 客户端配置
JedisClientConfiguration jedisClientConfiguration = jpcb.build();
return jedisClientConfiguration;
}
@Bean
public RedisStandaloneConfiguration redisStandaloneConfiguration() {
RedisStandaloneConfiguration redisStandaloneConfiguration =
new RedisStandaloneConfiguration();
// 设置主机地址
redisStandaloneConfiguration.setHostName("localhost");
// 设置默认数据库
redisStandaloneConfiguration.setDatabase(0);
// 设置密码
// redisStandaloneConfiguration.setPassword(RedisPassword.of("123456"));
// 设置端口
redisStandaloneConfiguration.setPort(6379);
return redisStandaloneConfiguration;
}
@Bean
public RedisConnectionFactory redisConnectionFactory(RedisStandaloneConfiguration redisStandaloneConfiguration,
JedisClientConfiguration jedisClientConfiguration) {
return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration);
}
}
使用 RedisTemplate
与 Spring Data 类似, Spring Data Redis 以模板的形式提供了数据访问方案,模板如下:
- RedisTemplate
- StringRedisTemplate
RedisTemplate 能够让我们持久化各种类型的 kye 和 value ,而 StringRedisTemplate 扩展了 RedisTemplate 只关注 String 类型。
RedisTemplate 常用方法
方法名 | 作用 |
---|---|
opsForValue() | 操作具有简单值的条目 |
opsForList() | 操作具有 List 值的条目 |
opsForSet() | 操作具有 set 值的条目 |
opsForHash() | 操作具有 hash 值的条目 |
boundValueOps(K) | 以绑定指定 key 的方式,操作具有简单值的条目 |
boundListOps(K) | 以绑定指定 key 的方式,操作具有 list 值的条目 |
boundSetOps(K) | 以绑定指定 key 的方式,操作具有 set 值的条目 |
boundHashOps(K) | 以绑定指定 key 的方式,操作具有 hash 值的条目 |
配置模板 Bean
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
return new StringRedisTemplate(redisConnectionFactory);
}
单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RootConfig.class)
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
/**
* 操作简单数据
*/
@Test
public void testSimpleValue() {
String kye = "name";
String value = "MarkLogZhu";
redisTemplate.opsForValue().set(kye, value);
String getValue = (String) redisTemplate.opsForValue().get(kye);
Assert.assertEquals(value,getValue);
}
/**
* 操作 List 数据
*/
@Test
public void testListValue(){
String key = "nameList";
List<String> nameList = new ArrayList<>();
nameList.add("张三");
nameList.add("李四");
nameList.add("王五");
redisTemplate.opsForList().rightPush(key,nameList);
List<String> getNameList =(List<String>) redisTemplate.opsForList().rightPop(key);
Assert.assertEquals(nameList,getNameList);
}
/**
* 操作 Set 数据
*/
@Test
public void testSetValue(){
String key = "nameSet";
Set nameSet = new HashSet();
nameSet.add("张三");
nameSet.add("李四");
nameSet.add("王五");
redisTemplate.opsForSet().add(key,nameSet);
Set getNameSet =(Set) redisTemplate.opsForSet().pop(key);
Assert.assertEquals(nameSet,getNameSet);
}
}
序列化器
当某个数据需要保存到 Redis 的时候, key 和 value 都会使用 Redis 的序列器(serializer) 进行序列化。Spring Data Redis 提供了多个序列化器:
- GenericToStringSerializer:使用 Spring 转换服务进行序列化
- JacksonJsonRedisSerializer:使用 Jackson1 将对象序列化为 JSON
- Jackson2JsonRedisSerializer:使用 Jackson2 将对象序列化为 JSON
- JdkSerializationRedisSerializer:使用 Java 序列化
- OxmSerializer:使用 **Spring O/X ** 映射的编排器和解排器实现序列化,用于 XML 序列化
- StringRedisSerializer:序列化 String 类型的 key 和 value
这些序列化器都实现了 RedisSerializer 接口,如果上述序列化器还不能满足,可以自己实现这个接口。
RedisTemplate 默认使用 JdkSerializationRedisSerializer , 而 StringRedisTemplate 默认使用 StringRedisSerializer。
配置序列化器
@Bean
public RedisTemplate<String ,?> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}