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);
    }
}
posted @ 2017-06-18 20:09 -.-| 阅读(...) 评论(...) 编辑 收藏