Spring Data Redis
前言
使用Jedis来操作Redis有两个明显的问题(我都能发现当然很明显):
- 需要手动关闭资源;
- 完全编码式的事务声明。
不过强大的Spring肯定会有对Redis的支持,于是我找到了Spring Data Redis
Spring Data Redis
Jedis的不足
- connection管理缺乏自动化,connection-pool的设计缺少必要的容器支持;
- 数据操作需要关注“序列化”/“反序列化”,因为jedis的客户端API接受的数据类型为string和byte,对结构化数据(json,xml,pojo等)操作需要额外的支持;
- 事务操作纯粹为硬编码;
- pub/sub功能,缺乏必要的设计模式支持,对于开发者而言需要关注的太多。
Spring Data Redis提供的功能
- 连接池自动管理,提供了一个高度封装的“RedisTemplate”类;
- 针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口;
- 提供了对key的“bound”(绑定)便捷化操作API,可以通过bound封装指定的key,然后进行一系列的操作而无须“显式”的再次指定Key,即BoundKeyOperations;
- 将事务操作封装,有容器控制。
- 针对数据的“序列化/反序列化”,提供了多种可选择策略(RedisSerializer)
- 基于设计模式,和JMS开发思路,将pub/sub的API设计进行了封装,使开发更加便捷。
序列化策略
Spring Data Redis 提供了四种serializer:
- JdkSerializationRedisSerializer ,使用JDK的序列化(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储;
- StringRedisSerializer,字符串编码,数据以string存储;
- JacksonJsonRedisSerializer,json格式存储;
- OxmSerializer,xml格式存储。
其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略,“JacksonJsonRedisSerializer”与“OxmSerializer”都是基于stirng存储,因此它们是较为“高级”的序列化(最终还是使用string解析以及构建java对象)。
RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”:
- keySerializer ,对于普通K-V操作时,key采取的序列化策略;
- valueSerializer,value采取的序列化策略;
- hashKeySerializer,在hash数据结构中,hash-key的序列化策略;
- hashValueSerializer,hash-value的序列化策略。
代码
maven依赖
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.4.RELEASE</version>
</dependency>
Spring配置
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<property name="maxTotal" value="${redis.pool.maxTotal}"/>
<property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}"/>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="hostName" value="${redis.url}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.auth}"/>
<property name="timeout" value="${redis.timeout}"/>
<property name="database" value="${redis.database}" />
<property name="usePool" value="true" />
<property name="poolConfig" ref="jedisPoolConfig" />
</bean>
<bean class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
</bean>
model
import java.io.Serializable;
/**
* Created by FJH on 2017/6/18.
*/
public class User implements Serializable{
private Long userId;
private String username;
private String loginName;
private String password;
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", username='" + username + '\'' +
", loginName='" + loginName + '\'' +
", password='" + password + '\'' +
'}';
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
dao
import cn.fjhdtp.maventest.dao.UserDao;
import cn.fjhdtp.maventest.model.User;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
/**
* Created by FJH on 2017/6/18.
*/
@Repository
public class UserDaoImpl implements UserDao {
@Resource
private RedisTemplate<Long, User> redisTemplate;
@Override
public void save(User user) {
ValueOperations<Long, User> valueOperations = redisTemplate.opsForValue();
valueOperations.set(user.getUserId(), user);
}
@Override
public User get(Long id) {
ValueOperations<Long, User> valueOperations = redisTemplate.opsForValue();
return valueOperations.get(id);
}
@Override
public void delete(Long id) {
ValueOperations<Long, User> valueOperations = redisTemplate.opsForValue();
RedisOperations<Long, User> redisOperations = valueOperations.getOperations();
redisOperations.delete(id);
}
}