Lettuce与Jedis
sprintboot 1.x.x的版本时默认使用的jedis客户端, 现在是sprintboot 2.x.x版本默认使用的lettuce客户端,两种客户端的区别如下:
Jedis是直连模式,在多个线程间共享一个Jedis实例时是线程不安全的,如果想要在多线程环境下使用Jedis,需要使用连接池,每个线程都去拿自己的Jedis实例,当连接数量增多时,物理连接成本就较高了。
Lettuce的连接是基于Netty的,连接实例可以在多个线程间共享,所以,一个多线程的应用可以使用同一个连接实例,而不用担心并发线程的数量当然这个也是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。通过异步的方式可以让我们更好的利用系统资源,而不用浪费线程等待网络或磁盘I/O。Lettuce是基于netty的,netty是一个多线程、事件驱动的I/O框架,所以Lettuce可以帮助我们充分利用异步的优势。 以下使用Lettuce
Lettuce参考:一起来学SpringBoot | 第九篇:整合Lettuce Redis_WinterChen的博客的博客-优快云博客
Jedis参考:SpringBoot 整合 Redis 使用详解(StringRedisTemplate 和 RedisTemplate 对比分析)_深寒色的猫丶的博客-优快云博客
引入依赖
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- jackson序列化 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.6</version>
</dependency>
配置文件
application.yml
spring:
application:
name: redis-module
redis:
host: 127.0.0.1
port: 6379
database: 0 #Redis索引0~15,默认为0
timeout: 10000 #连接超时时间
password: #密码(默认为空)
lettuce:
pool:
max-active: 200 # 连接池最大连接数(使用负值表示没有限制),默认8
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制),默认-1
max-idle: 10 # 连接池中的最大空闲连接,默认8
min-idle: 0 # 连接池中的最小空闲连接,默认0
各个版本的redis配置问题:springboot中各个版本的redis配置问题_spring-boot-starter-data-redis 版本_独步秋风的博客-优快云博客
配置类
redisConfig.java
RedisTemplate使用的是 JdkSerializationRedisSerializer 序列化对象
StringRedisTemplate使用的是 StringRedisSerializer 序列化String
序列化默认为使用JdkSerializationRedisSerializer,同时还有StringRedisSerializer,JacksonJsonRedisSerializer,OxmSerializer,GenericFastJsonRedisSerializer。
使用:Jackson2JsonRedisSerializer
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* RedisTemplate配置
* @param lettuceConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 设置序列化
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
使用:GenericJackson2JsonRedisSerializer
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* RedisTemplate配置
* @param lettuceConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 设置序列化
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setValueSerializer(jsonRedisSerializer );// value序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.setHashValueSerializer(jsonRedisSerializer );// Hash value序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
几种序列化区别
- JdkSerializationRedisSerializer: 序列化java对象,不是明文显示。被序列化的对象必须实现Serializable接口。
- StringRedisSerializer: 简单的字符串序列化,只能保存字符串,不能保存对象。
- GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化,也存在localdata反序列化的问题
- GenericFastJsonRedisSerializer: 会将数组反序列化为JSONArray
- GenericJackson2JsonRedisSerializer: 明文显示,还会显示字段的类型,可以强转。反序列化带泛型的数组类会报转换异常,也存在localdata反序列化的问题
- Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的
- JacksonJsonRedisSerializer: 序列化object对象为json字符串,在使用过程中,timestamp类型的数据以long类型存储,反序列化会出现问题,序列化带泛型的数据时,会以map的结构进行存储,反序列化是不能将map解析成对象
结论:
JdkSerializationRedisSerializer序列化后的长度最短,时间适中。
Jackson2JsonRedisSerializer序列化速度最快,长度适中
GenericJackson2JsonRedisSerializer序列化时间最长,长度最大
使用FastJson实现对象的序列化
pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
FastJsonRedisSerializer.java
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
/*
要实现对象的缓存,定义自己的序列化和反序列化器。使用阿里的fastjson来实现的比较多。
*/
public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
public FastJsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (null == t) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (null == bytes || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, clazz);
}
}
redisConfig.java
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
/**
* RedisTemplate配置
* @param lettuceConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
// 设置序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
// 配置redisTemplate
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
RedisSerializer<?> stringSerializer = new StringRedisSerializer();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
// value值的序列化采用fastJsonRedisSerializer
redisTemplate.setValueSerializer(fastJsonRedisSerializer);// value序列化
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);// Hash value序列化
redisTemplate.setKeySerializer(stringSerializer);// key序列化
redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
参考:springboot2.x使用redis作为缓存(使用fastjson序列化的方式,并调试反序列化异常)_zmc@的博客-优快云博客
工具类
RedisUtils
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtils {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private RedisTemplate<String, String> redisTemplateString;
/**
* 写入缓存
*
* @param key
* @param value
* @return boolean
*/
public boolean set(String key, Object value) {
boolean result = false;
try {
ValueOperations<String, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 写入缓存设置时效时间
*
* @param key
* @param value
* @return boolean
*/
public boolean set(String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations<String, Object> operations = redisTemplate.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 批量删除对应的value
*
* @param keys
*/
public void remove(String... keys) {
for (String key : keys) {
remove(key);
}
}
/**
* 批量删除key
*
* @param pattern
*/
public void removePattern(String pattern) {
Set<String> keys = redisTemplate.keys(pattern);
if (keys.size() > 0)
redisTemplate.delete(keys);
}
/**
* 删除对应的value
*
* @param key
*/
public void remove(String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
public long sSize(String key){
return redisTemplate.opsForSet().size(key);
}
/**
* 判断缓存中是否有对应的value
*
* @param key
* @return
*/
public boolean exists(String key) {
return redisTemplate.hasKey(key);
}
/**
* 读取缓存
*
* @param key
* @return
*/
public Object get(String key) {
Object result = null;
ValueOperations<String, Object> operations = redisTemplate.opsForValue();
result = operations.get(key);
return result;
}
public String getString(String key) {
String result = null;
ValueOperations<String, String> operations = redisTemplateString.opsForValue();
result = operations.get(key);
return result;
}
/**
* 哈希 添加
*
* @param key
* @param hashKey
* @param value
*/
public void hmSet(String key, Object hashKey, Object value) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
hash.put(key, hashKey, value);
}
/**
* 哈希获取数据
*
* @param key
* @param hashKey
* @return
*/
public Object hmGet(String key, Object hashKey) {
HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
return hash.get(key, hashKey);
}
public Map hmEntries(String key) {
HashOperations<String, String, String> hash = redisTemplate.opsForHash();
return hash.entries(key);
}
/**
* 列表添加
*
* @param k
* @param v
*/
public void lPush(String k, Object v) {
ListOperations<String, Object> list = redisTemplate.opsForList();
list.rightPush(k, v);
}
/**
* 列表获取
*
* @param k
* @param l
* @param l1
* @return
*/
public List<Object> lRange(String k, long l, long l1) {
ListOperations<String, Object> list = redisTemplate.opsForList();
return list.range(k, l, l1);
}
/**
* 集合添加
*
* @param key
* @param value
*/
public void setArray(String key, Object value) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
set.add(key, value);
}
/**
* 集合获取
*
* @param key
* @return
*/
public Set<Object> getArray(String key) {
SetOperations<String, Object> set = redisTemplate.opsForSet();
return set.members(key);
}
/**
* 有序集合添加
*
* @param key
* @param value
* @param scoure
*/
public void zAdd(String key, Object value, double scoure) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
zset.add(key, value, scoure);
}
/**
* 有序集合获取
*
* @param key
* @param scoure
* @param scoure1
* @return
*/
public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeByScore(key, scoure, scoure1);
}
public Set<ZSetOperations.TypedTuple<Object>> rangeWithScores(String key, long scoure, long scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.rangeWithScores(key, scoure, scoure1);
}
public Set<ZSetOperations.TypedTuple<Object>> reverseRangeWithScores(String key, long scoure, long scoure1) {
ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
return zset.reverseRangeWithScores(key, scoure, scoure1);
}
}
Redis设置Key过期时间
redis有四种命令可以用于设置键的生存时间和过期时间:
EXPIRE <KEY> <TTL>:将键的生存时间设为 ttl 秒
PEXPIRE <KEY> <TTL>:将键的生存时间设为 ttl 毫秒
EXPIREAT <KEY> <timestamp>:将键的过期时间设为 timestamp 所指定的秒数时间戳
PEXPIREAT <KEY> <timestamp>:将键的过期时间设为 timestamp 所指定的毫秒数时间戳.
其实以上几种处理方式都是根据PEXPIREAT来实现的,设置生存时间的时候是redis内部计算好时间之后在内存处理的,最终的处理都会转向PEXPIREAT。
1、2两种方式是设置一个过期的时间段,就是咱们处理验证码最常用的策略,设置三分钟或五分钟后失效,把分钟数转换成秒或毫秒存储到redis中。
3、4两种方式是指定一个过期的时间 ,比如优惠券的过期时间是某年某月某日,只是单位不一样。
Redis使用管道
// 读取:
List<Object> list = redisTemplate.executePipelined((RedisCallback<List<Object>>) connection -> {
for (String key : keyList) {
connection.hGetAll((key).getBytes());
}
return null;
});
int i = 0;
for (String key : keyList) {
result.put(key , list.get(i));
i++;
}
// 写入:
redisTemplate.executePipelined((RedisCallback)
connection -> {
list.forEach(object -> {
connection.set(key.getBytes(),value.getBytes());
});
return null;
});
ps:如果某一次需要执行大量的命令,不能放到一个 pipeline 中执行。数据量过多,网络传输延迟会增加,且会消耗 Redis 大量的内存。应该将大量的命令切分为多个 pipeline 分别执行。
参考:RedisTemplate使用PipeLine的总结_October-的博客-优快云博客
execute和 executePipelined:springboot Redistemplate的execute和 executePipelined_weixin_33721427的博客-优快云博客
RedisTempalte常用方法
Redis常用的数据类型
- String
- Hash
- List
- Set
- zSet
String类型
// 判断是否有key所对应的值,有则返回true,没有则返回false
redisTemplate.hasKey(key);
// 有则取出key值所对应的值
redisTemplate.opsForValue().get(key);
// 对key所储存的字符串值,获取指定偏移量上的位(bit)
redisTemplate.opsForValue().getBit(key, offset);
// 删除单个key值
redisTemplate.delete(key);
// 批量删除key,其中keys:Collection<K> keys
redisTemplate.delete(keys) ;
// 设置当前的key以及value值
redisTemplate.opsForValue().set(key, value);
// 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始
redisTemplate.opsForValue().set(key, value, offset);
// 设置当前的key以及value值并且设置过期时间
redisTemplate.opsForValue().set(key, value, timeout, unit);
// 将值 value 关联到 key,并将 key 的过期时间设为 timeout
redisTemplate.opsForValue().set(key, value, timeout, unit);
// 将二进制第offset位值变为value
redisTemplate.opsForValue().setBit(key, offset, value);
// 重新设置key对应的值,如果存在返回false,否则返回true
redisTemplate.opsForValue().setIfAbsent(key, value);
// 在原有的值基础上新增字符串到末尾
redisTemplate.opsForValue().append(key, value);
// 将当前传入的key值序列化为byte[]类型
redisTemplate.dump(key);
// 获取字符串的长度
redisTemplate.opsForValue().size(key);
// 从redis中随机取出一个key
redisTemplate.randomKey();
// 设置过期时间
public Boolean expire(String key, long timeout, TimeUnit unit) {
return redisTemplate.expire(key, timeout, unit);
}
// 设置过期时间
public Boolean expireAt(String key, Date date) {
return redisTemplate.expireAt(key, date);
}
// 查找匹配的key值,返回一个Set集合类型
public Set<String> getPatternKey(String pattern) {
return redisTemplate.keys(pattern);
}
// 修改redis中key的名称
public void renameKey(String oldKey, String newKey) {
redisTemplate.rename(oldKey, newKey);
}
// 返回传入key所存储的值的类型
public DataType getKeyType(String key) {
return redisTemplate.type(key);
}
// 如果旧值存在时,将旧值改为新值
public Boolean renameOldKeyIfAbsent(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
// 返回当前key所对应的剩余过期时间
public Long getExpire(String key) {
return redisTemplate.getExpire(key);
}
// 返回剩余过期时间并且指定时间单位
public Long getExpire(String key, TimeUnit unit) {
return redisTemplate.getExpire(key, unit);
}
// 将key持久化保存
public Boolean persistKey(String key) {
return redisTemplate.persist(key);
}
// 将当前数据库的key移动到指定redis中数据库当中
public Boolean moveToDbIndex(String key, int dbIndex) {
return redisTemplate.move(key, dbIndex);
}
// 返回key中字符串的子字符
public String getCharacterRange(String key, long start, long end) {
return redisTemplate.opsForValue().get(key, start, end);
}
// 将旧的key设置为value,并且返回旧的key
public String setKeyAsValue(String key, String value) {
return redisTemplate.opsForValue().getAndSet(key, value);
}
// 批量获取值
public List<String> multiGet(Collection<String> keys) {
return redisTemplate.opsForValue().multiGet(keys);
}
// 以增量的方式将double值存储在变量中
public Double incrByDouble(String key, double increment) {
return redisTemplate.opsForValue().increment(key, increment);
}
// 通过increment(K key, long delta)方法以增量方式存储long值(正值则自增,负值则自减)
public Long incrBy(String key, long increment) {
return redisTemplate.opsForValue().increment(key, increment);
}
// 如果对应的map集合名称不存在,则添加否则不做修改
Map valueMap = new HashMap();
valueMap.put("valueMap1","map1");
valueMap.put("valueMap2","map2");
valueMap.put("valueMap3","map3");
redisTemplate.opsForValue().multiSetIfAbsent(valueMap);
// 设置map集合到redis
Map valueMap = new HashMap();
valueMap.put("valueMap1","map1");
valueMap.put("valueMap2","map2");
valueMap.put("valueMap3","map3");
redisTemplate.opsForValue().multiSet(valueMap);
Hash类型
// 获取变量中的指定map键的值
redisTemplate.opsForHash().get(key, field)
// 新增hashMap值
redisTemplate.opsForHash().put(key, hashKey, value)
// 获取所有hash表中字段
redisTemplate.opsForHash().keys(key)
// 获取hash表中字段的数量
redisTemplate.opsForHash().size(key)
// 获取变量中的键值对
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
// 以map集合的形式添加键值对
public void hPutAll(String key, Map<String, String> maps) {
redisTemplate.opsForHash().putAll(key, maps);
}
// 仅当hashKey不存在时才设置
public Boolean hashPutIfAbsent(String key, String hashKey, String value) {
return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value);
}
// 删除一个或者多个hash表字段
public Long hashDelete(String key, Object... fields) {
return redisTemplate.opsForHash().delete(key, fields);
}
// 查看hash表中指定字段是否存在
public boolean hashExists(String key, String field) {
return redisTemplate.opsForHash().hasKey(key, field);
}
// 给哈希表key中的指定字段的整数值加上增量increment
public Long hashIncrBy(String key, Object field, long increment) {
return redisTemplate.opsForHash().increment(key, field, increment);
}
public Double hIncrByDouble(String key, Object field, double delta) {
return redisTemplate.opsForHash().increment(key, field, delta);
}
// 获取hash表中存在的所有的值
public List<Object> hValues(String key) {
return redisTemplate.opsForHash().values(key);
}
// 匹配获取键值对,ScanOptions.NONE为获取全部键对
public Cursor<Entry<Object, Object>> hashScan(String key, ScanOptions options) {
return redisTemplate.opsForHash().scan(key, options);
}
List类型
// 通过索引获取列表中的元素
redisTemplate.opsForList().index(key, index)
// 获取列表指定范围内的元素(start开始位置, 0是开始位置,end 结束位置, -1返回所有)
redisTemplate.opsForList().range(key, start, end)
// 存储在list的头部,即添加一个就把它放在最前面的索引处
redisTemplate.opsForList().leftPush(key, value)
// 把多个值存入List中(value可以是多个值,也可以是一个Collection value)
redisTemplate.opsForList().leftPushAll(key, value)
// List存在的时候再加入
redisTemplate.opsForList().leftPushIfPresent(key, value)
// 如果pivot处值存在则在pivot前面添加
redisTemplate.opsForList().leftPush(key, pivot, value)
// 按照先进先出的顺序来添加(value可以是多个值,或者是Collection var2)
redisTemplate.opsForList().rightPush(key, value)
redisTemplate.opsForList().rightPushAll(key, value)
// 在pivot元素的右边添加值
redisTemplate.opsForList().rightPush(key, pivot, value)
// 设置指定索引处元素的值
redisTemplate.opsForList().set(key, index, value)
// 移除并获取列表中第一个元素(如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止)
redisTemplate.opsForList().leftPop(key)
redisTemplate.opsForList().leftPop(key, timeout, unit)
// 移除并获取列表最后一个元素
redisTemplate.opsForList().rightPop(key)
redisTemplate.opsForList().rightPop(key, timeout, unit)
// 从一个队列的右边弹出一个元素并将这个元素放入另一个指定队列的最左边
redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey)
redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, unit)
// 删除集合中值等于value的元素(index=0, 删除所有值等于value的元素; index>0, 从头部开始删除第一个值等于value的元素; index<0, 从尾部开始删除第一个值等于value的元素)
redisTemplate.opsForList().remove(key, index, value)
// 将List列表进行剪裁
redisTemplate.opsForList().trim(key, start, end)
// 获取当前key的List列表长度
redisTemplate.opsForList().size(key)
Set类型
// 添加元素
redisTemplate.opsForSet().add(key, values)
// 移除元素(单个值、多个值)
redisTemplate.opsForSet().remove(key, values)
// 删除并且返回一个随机的元素
redisTemplate.opsForSet().pop(key)
// 获取集合的大小
redisTemplate.opsForSet().size(key)
// 判断集合是否包含value
redisTemplate.opsForSet().isMember(key, value)
// 获取两个集合的交集(key对应的无序集合与otherKey对应的无序集合求交集)
redisTemplate.opsForSet().intersect(key, otherKey)
// 获取多个集合的交集(Collection var2)
redisTemplate.opsForSet().intersect(key, otherKeys)
// key集合与otherKey集合的交集存储到destKey集合中(其中otherKey可以为单个值或者集合)
redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey)
// key集合与多个集合的交集存储到destKey无序集合中
redisTemplate.opsForSet().intersectAndStore(key, otherKeys, destKey)
// 获取两个或者多个集合的并集(otherKeys可以为单个值或者是集合)
redisTemplate.opsForSet().union(key, otherKeys)
// key集合与otherKey集合的并集存储到destKey中(otherKeys可以为单个值或者是集合)
redisTemplate.opsForSet().unionAndStore(key, otherKey, destKey)
// 获取两个或者多个集合的差集(otherKeys可以为单个值或者是集合)
redisTemplate.opsForSet().difference(key, otherKeys)
// 差集存储到destKey中(otherKeys可以为单个值或者集合)
redisTemplate.opsForSet().differenceAndStore(key, otherKey, destKey)
// 随机获取集合中的一个元素
redisTemplate.opsForSet().randomMember(key)
// 获取集合中的所有元素
redisTemplate.opsForSet().members(key)
// 随机获取集合中count个元素
redisTemplate.opsForSet().randomMembers(key, count)
// 获取多个key无序集合中的元素(去重),count表示个数
redisTemplate.opsForSet().distinctRandomMembers(key, count)
// 遍历set类似于Interator(ScanOptions.NONE为显示所有的)
redisTemplate.opsForSet().scan(key, options)
zSet类型
// 添加元素(有序集合是按照元素的score值由小到大进行排列)
redisTemplate.opsForZSet().add(key, value, score)
// 删除对应的value,value可以为多个值
redisTemplate.opsForZSet().remove(key, values)
// 增加元素的score值,并返回增加后的值
redisTemplate.opsForZSet().incrementScore(key, value, delta)
// 返回元素在集合的排名,有序集合是按照元素的score值由小到大排列
redisTemplate.opsForZSet().rank(key, value)
// 返回元素在集合的排名,按元素的score值由大到小排列
redisTemplate.opsForZSet().reverseRank(key, value)
// 获取集合中给定区间的元素(start 开始位置,end 结束位置, -1查询所有)
redisTemplate.opsForZSet().reverseRangeWithScores(key, start,end)
// 按照Score值查询集合中的元素,结果从小到大排序
redisTemplate.opsForZSet().reverseRangeByScore(key, min, max)
redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max)
//返回值为:Set<ZSetOperations.TypedTuple<V>>
// 从高到低的排序集中获取分数在最小和最大值之间的元素
redisTemplate.opsForZSet().reverseRangeByScore(key, min, max, start, end)
// 根据score值获取集合元素数量
redisTemplate.opsForZSet().count(key, min, max)
// 获取集合的大小
redisTemplate.opsForZSet().size(key)
redisTemplate.opsForZSet().zCard(key)
// 获取集合中key、value元素对应的score值
redisTemplate.opsForZSet().score(key, value)
// 移除指定索引位置处的成员
redisTemplate.opsForZSet().removeRange(key, start, end)
// 移除指定score范围的集合成员
redisTemplate.opsForZSet().removeRangeByScore(key, min, max)
// 获取key和otherKey的并集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)
redisTemplate.opsForZSet().unionAndStore(key, otherKey, destKey)
// 获取key和otherKey的交集并存储在destKey中(其中otherKeys可以为单个字符串或者字符串集合)
redisTemplate.opsForZSet().intersectAndStore(key, otherKey, destKey)
// 遍历集合(和iterator一模一样)
Cursor<TypedTuple<Object>> scan = opsForZSet.scan("test3", ScanOptions.NONE);
while (scan.hasNext()){
ZSetOperations.TypedTuple<Object> item = scan.next();
System.out.println(item.getValue() + ":" + item.getScore());
}