RedisTemplate的使用

一. RedisTemplate类图

在这里插入图片描述

其中:

  1. RedisAccessor用来设置ConnectFactory即spring初始化时, 检查设置redisTempalte的序列化实例的
  2. RedisOperations用来定义通用命令(与数据结构类型无关)及opsForXXX、execute等所有操作
  3. StringRedisTemplate是将定序列化器全部为StringSerializer的子类

二. RedisTemplate主要API

1. 连接池

配置redis连接参数及连接管理

private RedisConnectionFactory connectionFactory;//管理redis连接和配置参数

如果用cluster模式或codis等框架, 只需set对应的RedisConnectionFactory实现即可.


2. 序列化器

序列化器, 用来完成读写时对象和byte[] 的相互转换.

//开启事务,事务的前提操作是基于同一个连接.否则可能多节点是可能MULTI/EXEC等打到不同节点
private boolean enableTransactionSupport = false;
private boolean exposeConnection = false;//是否对连接进行暴露
private boolean initialized = false;//执行afterProperties后的初始化标志,不初始化会报错
private boolean enableDefaultSerializer = true;//如果未设置序列化器,是否使用默认
private RedisSerializer<?> defaultSerializer;//默认的序列化器
private RedisSerializer<String> stringSerializer = new StringRedisSerializer();//暴露给应用的String类型的的序列化器


private RedisSerializer keySerializer = null;//负责所有类型的key序列化
private RedisSerializer valueSerializer = null;
private RedisSerializer hashKeySerializer = null;
private RedisSerializer hashValueSerializer = null;
//string类型:value采用valueSerializer
//hash类型:field采用hashKeySerializer,value采用hashValueSerializer
//list类型:value采用valueSerializer
//set类型:member采用valueSerializer
//zset类型:member采用valueSerializer
//script类型:args和result均用valueSerializer

如果不设置, 默认为JdkSerializationRedisSerializer:

public void serialize(Object object, OutputStream outputStream) throws IOException {
        if (!(object instanceof Serializable)) {
            throw new IllegalArgumentException(this.getClass().getSimpleName() + " requires a Serializable payload but received an object of type [" + object.getClass().getName() + "]");
        } else {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
            objectOutputStream.writeObject(object);
            objectOutputStream.flush();
        }
}

默认的JDK占用空间比较大,可读性差, 一般是先将对象转化为JSON串, 再储存到redis. 当然为了节省空间, 也可以使用kryo/protobuf等框架进行序列化, 但可读性比较差.


3. 各类型的API

private ScriptExecutor<K> scriptExecutor;//执行script时的执行器
private ValueOperations<K, V> valueOps;//opsForValue返回String操作API
private ListOperations<K, V> listOps;//opsForList返回List操作API
private SetOperations<K, V> setOps;//opsForSet返回Set操作API
private ZSetOperations<K, V> zSetOps;//opsForZset返回Zset操作API
private GeoOperations<K, V> geoOps;
private HyperLogLogOperations<K, V> hllOps;
//注意: opsForHash每次返回新的HashOprerations操作实例

其中各数据类型的操作API见对应的Operations接口定义.


4. execute回调API

模版方法: RedisTemplate提供Connection, CallBack提供执行逻辑

定义在RedisOperations接口中:

<T> T execute(RedisCallback<T> var1);

<T> T execute(SessionCallback<T> var1);

List<Object> executePipelined(RedisCallback<?> var1);

List<Object> executePipelined(RedisCallback<?> var1, RedisSerializer<?> var2);

List<Object> executePipelined(SessionCallback<?> var1);

List<Object> executePipelined(SessionCallback<?> var1, RedisSerializer<?> var2);

<T> T execute(RedisScript<T> var1, List<K> var2, Object... var3);

4.1 RedisCallback

RedisCallback基于原生RedisConnection的命令来操作. 支持pipeLine. RedisCallback执行期间使用的是同一个连接操作, 不绑定到线程(意味着无法保证连续两个Callback是同一个的连接), 开启事务执行事务时需要自己执行MULTI/EXE命令

public interface RedisCallback<T> {
    T doInRedis(RedisConnection var1) throws DataAccessException;
}

4.2 SessionCallback

SessionCallback基于RedisOperations的命令来操作. 支持pipeLine. SessionCallback执行期间默认会将Connection绑定到线程, SessionCallback执行完成后会解绑(意味着无法保证连续两个Callback是同一个的连接), 这样执行期间通过RedisConnectionUtils.getConnection获取连接时可以复用同一个连接, 基于RedisOperations的操作大多是基于RedisCallback的回调来操作, 基本都是通过RedisConnectionUtils.getConnection复用连接, 开启事务后框架会帮执行MULTI/EXE命令

public interface SessionCallback<T> {
    <K, V> T execute(RedisOperations<K, V> var1) throws DataAccessException;
}

4.3 executePipelined

这个是redis原本支持的功能, 多个操作时可以打到先发送命令不必等返回最后统一返回的效果. 可以理解为Future一样的效果. pipeLine的前提是同一个连接.

如果是redis集群,执行pipeLine时命令数量不要太多,否则可能导致redisServer关闭了链接导致ConnectionReset异常(建议小于200分页)


4.4 StringRedisTemplate

如果使用RedisTemplate前都已经将对象转化为String了(一般为JSON格式), 那就只需要将String和byte[]进行转化了. 此时可以使用StringRedisTemplate. 默认调用String.getByte(“UTF-8”)来序列化.

public class StringRedisTemplate extends RedisTemplate<String, String> {
    public StringRedisTemplate() {
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        this.setKeySerializer(stringSerializer);
        this.setValueSerializer(stringSerializer);
        this.setHashKeySerializer(stringSerializer);
        this.setHashValueSerializer(stringSerializer);
    }
    public StringRedisTemplate(RedisConnectionFactory connectionFactory) {
        this();
        this.setConnectionFactory(connectionFactory);
        this.afterPropertiesSet();//使用RedisTemplate,如果没集成spring需要手动调用.这里简化了操作
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值