文章目录
springBoot集成redis
- 引入redis的jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
- yml配置
spring:
redis:
port: #redis的端口号默认端口是6379
password: #密码
host: 127.0.0.1
timeout: 5000
- config
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//创建RedisTemplate模板对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
//将redis的连接工厂与对象绑定
template.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的key也采用String的序列化方式,需要配置一下StringSerializer,不然key会乱码 /XX/XX
template.setHashKeySerializer(stringRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
- 示例
@Resource
private RedisTemplate redisTemplate;
/**
* 获取redis的数据
* @return
*/
public Boolean getRedisImg() {
String o = (String) redisTemplate.opsForValue().get(log);
if (StringUtils.isEmpty(o)) {
return false;
}
return true;
}
/**
* 生成key
* @return
*/
public Boolean doRedisImg() {
redisTemplate.opsForValue().set(log,"你好");
return true;
}
redisTemplate常用API:
package com.hl.chapter29.web;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* 测试接口
*/
@Controller
public class DemoController {
@Autowired
private RedisTemplate redisTemplate;
/**
* String类型
*/
@PostMapping(value = "/string")
@ResponseBody
public String stringTest(HttpServletRequest request, @RequestBody String req) {
// 插入一个key值
redisTemplate.opsForValue().set("a", 1000);
// 判断是否有key对应的值,有返回true,没有返回false
boolean isExist = redisTemplate.hasKey("a");
System.out.println(isExist);
// 取出key对应的值
redisTemplate.opsForValue().get("a");
// 删除某个key
redisTemplate.delete("a");
// 批量删除key
List keys = new ArrayList<String>();
keys.add("a");
keys.add("b");
redisTemplate.delete(keys);
// 将当前传入的key值序列化为btye[]类型
redisTemplate.opsForValue().set("b", 2000);
System.out.println(redisTemplate.dump("b"));
// 设置过期时间
redisTemplate.expire("b", 10000, TimeUnit.MILLISECONDS);
// System.out.println(redisTemplate.expireAt("b", new Date()));
// 查找匹配的key值,返回set集合
redisTemplate.opsForValue().set("a", 1100);
redisTemplate.opsForValue().set("c", 3000);
System.out.println(redisTemplate.keys("*"));
// 修改key名称
redisTemplate.rename("a", "aa");
// 返回传入key存储的数据类型
System.out.println(redisTemplate.type("aa"));
// 随机取出一个key
System.out.println(redisTemplate.randomKey());
// 返回当前key剩余过期时间
System.out.println(redisTemplate.getExpire("aa"));
System.out.println(redisTemplate.getExpire("aa", TimeUnit.SECONDS));
// 将key持久化
redisTemplate.persist("c");
// 将当前key迁移到指定数据库中
redisTemplate.move("c", 1);
// 返回部分字符
System.out.println(redisTemplate.opsForValue().get("a", 0, 2));
// 批量获取值
List keys2 = new ArrayList();
keys2.add("a");
keys2.add("b");
keys2.add("c");
System.out.println(redisTemplate.opsForValue().multiGet(keys2));
// 新增字符串
redisTemplate.opsForValue().append("a", "1000");
// 如果对应的map集合名称不存在,则添加否则不做修改
Map valueMap = new HashMap();
valueMap.put("valueMap1", "map1");
valueMap.put("valueMap2", "map2");
valueMap.put("valueMap3", "map3");
redisTemplate.opsForValue().multiSetIfAbsent(valueMap);
// 设置map集合到redis
Map valueMap2 = new HashMap();
valueMap2.put("valueMap1", "map1");
valueMap2.put("valueMap2", "map2");
valueMap2.put("valueMap3", "map3");
redisTemplate.opsForValue().multiSet(valueMap2);
// 获取字符串的长度
redisTemplate.opsForValue().size("a");
// 重新设置key对应的值,如果存在返回false,否则返回true
redisTemplate.opsForValue().setIfAbsent("a", 33);
// 将值 value 关联到 key,并将 key 的过期时间设为 timeout
redisTemplate.opsForValue().set("a", 2000, 10, TimeUnit.HOURS);
// 将二进制第offset位值变为value
// redisTemplate.opsForValue().setBit(key, offset, value);
// 对key所储存的字符串值,获取指定偏移量上的位(bit)
// redisTemplate.opsForValue().getBit(key, offset);
return JSONObject.parseObject(req).toJSONString();
}
/**
* hash类型
*/
@RequestMapping(value = "/hash")
@ResponseBody
public String hashTest(HttpServletRequest request) {
// 新增hashMap值
redisTemplate.opsForHash().put("hash", "a", "第一个");
// 获取指定map键是否有值,有就返回,没有返回null
System.out.println(redisTemplate.opsForHash().get("hash", "a"));
// 获取指定key中所有键值对
redisTemplate.opsForHash().put("hash", "b", "第二个");
redisTemplate.opsForHash().put("hash", "c", "第三个");
System.out.println(redisTemplate.opsForHash().entries("hash"));
// 以Map集合的方式添加键值对
Map map = new HashMap<String, String>();
map.put("d", "第四个");
map.put("e", "第五个");
redisTemplate.opsForHash().putAll("hash", map);
System.out.println(redisTemplate.opsForHash().entries("hash"));
// 仅当hashKey不存在时才设置
redisTemplate.opsForHash().putIfAbsent("hash", "a", "不是第一个了");
redisTemplate.opsForHash().putIfAbsent("hash", "f", "第六个");
System.out.println(redisTemplate.opsForHash().entries("hash"));
// 删除一个或多个hash表字段
redisTemplate.opsForHash().delete("hash", "e", "f");
System.out.println(redisTemplate.opsForHash().entries("hash"));
// 查看hash表中指定字段是否存在
System.out.println(redisTemplate.opsForHash().hasKey("hash", "f"));
// 给hash表中指定字段的整数值加上增量increment
redisTemplate.opsForHash().put("hash", "e", 10);
redisTemplate.opsForHash().increment("hash", "e", 10);
System.out.println(redisTemplate.opsForHash().get("hash", "e"));
// 给hash表中指定字段的浮点值加上increment
// redisTemplate.opsForHash().put("hash", "f", 15.5);
// redisTemplate.opsForHash().increment("hash", "f", 21.1);
// System.out.println(redisTemplate.opsForHash().get("hash", "f"));
// 获取hash表中所有字段
System.out.println(redisTemplate.opsForHash().keys("hash"));
// 获取hash表中字段数量
System.out.println(redisTemplate.opsForHash().size("hash"));
// 获取hash表中存在的所有值
System.out.println(redisTemplate.opsForHash().values("hash"));
// 匹配获取键值对
try {
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan("hash", ScanOptions.NONE);
while (cursor.hasNext()) {
Map.Entry<Object, Object> entry = cursor.next();
Object key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + ": " + value);
}
cursor.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* list类型
*/
@RequestMapping(value = "/list")
@ResponseBody
public String listTest(HttpServletRequest request) {
// 向列表中头部添加元素
redisTemplate.opsForList().leftPush("list", "第一个list元素");
// 通过index获取列表中的元素
System.out.println(redisTemplate.opsForList().index("list", 0));
// 把多个值存入列表头部
redisTemplate.opsForList().leftPushAll("list", "第二个list元素", "第三个list元素", "第四个list元素");
// 获取列表指定范围内元素,start起始位置,end结束位置,-1返回所有
System.out.println(redisTemplate.opsForList().range("list", 0, 3));
// list存在的时候再加入
redisTemplate.opsForList().leftPushIfPresent("list", "第六个list元素");
System.out.println(redisTemplate.opsForList().range("list", 0, -1));
// 在pivot值存在时在pivot前面添加
redisTemplate.opsForList().leftPush("list", "第六个list元素", "第五个半list元素");
System.out.println(redisTemplate.opsForList().range("list", 0, -1));
// 按照先进先出的原则添加多个值
redisTemplate.opsForList().rightPush("list", "第七个list元素");
redisTemplate.opsForList().rightPushAll("list", "第八个list元素", "第九个list元素");
System.out.println(redisTemplate.opsForList().range("list", 0, -1));
// 在pivot右边添加值
redisTemplate.opsForList().rightPush("list", "第七个list元素", "第七个半list元素");
System.out.println(redisTemplate.opsForList().range("list", 0, -1));
// 设置指定索引处元素的值
redisTemplate.opsForList().set("list", 5, "修改后的list元素");
// 移除并获取列表中第一个元素
System.out.println(redisTemplate.opsForList().leftPop("list"));
System.out.println(redisTemplate.opsForList().leftPop("list", 10, TimeUnit.SECONDS));
// 移除并获取列表中最后一个元素
System.out.println(redisTemplate.opsForList().rightPop("list"));
System.out.println(redisTemplate.opsForList().rightPop("list", 8, TimeUnit.SECONDS));
// 从一个列表右边弹出一个元素并将该元素插入另一个列表的左边
redisTemplate.opsForList().rightPopAndLeftPush("list", "list2");
redisTemplate.opsForList().rightPopAndLeftPush("list", "list2", 10, TimeUnit.SECONDS);
// 删除列表中值等于指定value的元素,index=0删除所有,index>0删除头部开始第一个,index<0删除尾部开始第一个
redisTemplate.opsForList().remove("list", 0, "第三个list元素");
System.out.println(redisTemplate.opsForList().range("list", 0, -1));
// 列表进行裁剪
redisTemplate.opsForList().trim("list", 1, 4);
System.out.println(redisTemplate.opsForList().range("list", 0, -1));
// 获取当前列表长度
System.out.println(redisTemplate.opsForList().size("list"));
return null;
}
/**
* set类型
*/
@GetMapping(value = "/set")
@ResponseBody
public String setTest(HttpServletRequest request) {
// 添加元素
redisTemplate.opsForSet().add("set", "第一个set元素");
redisTemplate.opsForSet().add("set", "第二个set元素");
redisTemplate.opsForSet().add("set", "第三个set元素");
redisTemplate.opsForSet().add("set", "第四个set元素");
redisTemplate.opsForSet().add("set", "第五个set元素");
// 获取集合中所有元素
System.out.println(redisTemplate.opsForSet().members("set"));
// 移除元素
redisTemplate.opsForSet().remove("set", "第一个set元素", "第三个set元素");
System.out.println(redisTemplate.opsForSet().members("set"));
// 删除并返回一个随机元素
System.out.println(redisTemplate.opsForSet().pop("set"));
// 获取集合大小
System.out.println(redisTemplate.opsForSet().size("set"));
// 判断集合是否包含value
System.out.println(redisTemplate.opsForSet().isMember("set", "第四个set元素"));
redisTemplate.opsForSet().add("otherSet", "第一个set元素");
redisTemplate.opsForSet().add("otherSet", "第二个set元素");
redisTemplate.opsForSet().add("otherSet", "第三个set元素");
redisTemplate.opsForSet().add("otherSet", "第四个set元素");
// 获取两个集合的交集
System.out.println(redisTemplate.opsForSet().intersect("set", "otherSet"));
// 获取多个集合的交集
redisTemplate.opsForSet().add("thirdSet", "第二个set元素");
Set otherKeys = new HashSet();
otherKeys.add("otherSet");
otherKeys.add("thirdSet");
System.out.println(redisTemplate.opsForSet().intersect("set", otherKeys));
// set集合与otherSet集合的交集存储到targetSet集合中
redisTemplate.opsForSet().intersectAndStore("set", "otherSet", "targetSet");
System.out.println(redisTemplate.opsForSet().members("targetSet"));
// set集合与多个集合的交集存储到targetSet集合中
redisTemplate.opsForSet().intersectAndStore("set", otherKeys, "targetSet");
System.out.println(redisTemplate.opsForSet().members("targetSet"));
// 获取两个或者多个集合的并集
System.out.println(redisTemplate.opsForSet().union("set", "otherSet"));
System.out.println(redisTemplate.opsForSet().union("set", otherKeys));
// set集合与多个集合的并集存储到targetSet集合中
redisTemplate.opsForSet().unionAndStore("set", otherKeys, "targetSet2");
System.out.println(redisTemplate.opsForSet().members("targetSets"));
// 获取两个或者多个集合的差集
System.out.println(redisTemplate.opsForSet().difference("set", otherKeys));
// 差集存储到targetSet中
redisTemplate.opsForSet().unionAndStore("set", otherKeys, "targetSet3");
System.out.println(redisTemplate.opsForSet().members("targetSet3"));
// 随机获取集合中的一个元素
System.out.println(redisTemplate.opsForSet().randomMember("set"));
// 随机获取集合中若干个元素
System.out.println(redisTemplate.opsForSet().randomMembers("set", 5));
// 遍历set,类似于iterator
try {
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForSet().scan("set", ScanOptions.NONE);
while (cursor.hasNext()) {
System.out.println(cursor.next());
}
cursor.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* zset类型
*/
@GetMapping(value = "/zset")
@ResponseBody
public String zsetTest(HttpServletRequest request) {
// 添加元素,有序集合按照score的值从小到大排序
redisTemplate.opsForZSet().add("zset", "第一个zset", 100);
redisTemplate.opsForZSet().add("zset", "第二个zset", 110);
redisTemplate.opsForZSet().add("zset", "第三个zset", 120);
redisTemplate.opsForZSet().add("zset", "第四个zset", 130);
redisTemplate.opsForZSet().add("zset", "第五个zset", 140);
// 获取元素在集合中的排名,按照score值从小到大排序
System.out.println("从小到大:" + redisTemplate.opsForZSet().rank("zset", "第二个zset"));
// 获取元素在集合中的排名,按照score值从大到小排序
System.out.println("从大到小:" + redisTemplate.opsForZSet().reverseRank("zset", "第二个zset"));
System.out.println("--------------------------------------");
// 获取集合中给定区间的元素,start开始位置,end结束位置,-1查询所有(从小到大)
// 返回值为:Set<ZSetOperations.TypedTuple<V>>
Iterator iterator = redisTemplate.opsForZSet().rangeWithScores("zset", 0, -1).iterator();
while (iterator.hasNext()) {
ZSetOperations.TypedTuple typedTuple = (ZSetOperations.TypedTuple) iterator.next();
System.out.println("从小到大:" + typedTuple.getValue() + ", " + typedTuple.getScore());
}
System.out.println("--------------------------------------");
// 获取集合中给定区间的元素,start开始位置,end结束位置,-1查询所有(从大到小)
Iterator iterator3 = redisTemplate.opsForZSet().reverseRangeWithScores("zset", 0, -1).iterator();
while (iterator3.hasNext()) {
ZSetOperations.TypedTuple typedTuple3 = (ZSetOperations.TypedTuple) iterator3.next();
System.out.println("从大到小:" + typedTuple3.getValue() + ", " + typedTuple3.getScore());
}
System.out.println("--------------------------------------");
// 按照score值查询集合中的元素,结果从小到大排序
System.out.println("从小到大:" + redisTemplate.opsForZSet().rangeByScore("zset", 100, 200));
Iterator iterator4 = redisTemplate.opsForZSet().rangeByScoreWithScores("zset", 100, 200).iterator();
while (iterator4.hasNext()) {
ZSetOperations.TypedTuple typedTuple4 = (ZSetOperations.TypedTuple) iterator4.next();
System.out.println("从小到大:" + typedTuple4.getValue() + ", " + typedTuple4.getScore());
}
System.out.println("--------------------------------------");
// 按照score值查询集合中的元素,结果从大到小排序
System.out.println("从大到小:" + redisTemplate.opsForZSet().reverseRangeByScore("zset", 100, 200));
Iterator iterator5 = redisTemplate.opsForZSet().reverseRangeByScoreWithScores("zset", 100, 200).iterator();
while (iterator5.hasNext()) {
ZSetOperations.TypedTuple typedTuple5 = (ZSetOperations.TypedTuple) iterator5.next();
System.out.println("从大到小:" + typedTuple5.getValue() + ", " + typedTuple5.getScore());
}
System.out.println("--------------------------------------");
// 从大到小排序获取集合中score在给定最大最小范围内的元素
System.out.println("从大到小:" + redisTemplate.opsForZSet().reverseRangeByScore("zset", 100, 1000, 0, -1));
System.out.println("--------------------------------------");
// 根据score获取集合元素数量
System.out.println(redisTemplate.opsForZSet().count("zset", 100, 150));
System.out.println("--------------------------------------");
// 获取集合大小
System.out.println(redisTemplate.opsForZSet().size("zset"));
System.out.println(redisTemplate.opsForZSet().zCard("zset"));
System.out.println("--------------------------------------");
// 获取集合中key value 对应的score
System.out.println(redisTemplate.opsForZSet().score("zset", "第三个zset"));
System.out.println("--------------------------------------");
// 移除指定索引位置的元素
redisTemplate.opsForZSet().removeRange("zset", 0, 1);
System.out.println(redisTemplate.opsForZSet().range("zset", 0, -1));
System.out.println("--------------------------------------");
// 获取key 和otherKey的交集并存储在targetKey
redisTemplate.opsForZSet().add("otherZset", "第二个zset", 200);
redisTemplate.opsForZSet().add("otherZset", "第三个zset", 200);
redisTemplate.opsForZSet().intersectAndStore("zset", "otherZset", "targetZset");
System.out.println(redisTemplate.opsForZSet().range("targetZset", 0, -1));
System.out.println("--------------------------------------");
// 获取key和otherKey的并集并且存储在targetKey中
redisTemplate.opsForZSet().unionAndStore("zset", "otherZset", "fourthZset");
System.out.println(redisTemplate.opsForZSet().range("fourthZset", 0, -1));
System.out.println("--------------------------------------");
// 遍历集合
try {
Cursor<ZSetOperations.TypedTuple> cursor = redisTemplate.opsForZSet().scan("zset", ScanOptions.NONE);
while (cursor.hasNext()) {
ZSetOperations.TypedTuple typedTuple = cursor.next();
System.out.println(typedTuple.getValue() + ", " + typedTuple.getScore());
}
cursor.close();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
redis的工具类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis工具类
*
*
*/
@Component
public final class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return true 成功 false 失败
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
*
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通缓存获取
*
* @param key 键
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public <T> T get(String key, Class<T> clazz) {
Object obj = key == null ? null : redisTemplate.opsForValue().get(key);
if (clazz.isInstance(obj)) {
return clazz.cast(obj);
}
return null;
}
/**
* 普通缓存放入
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 如果key已存在就不执行,并返回false 不存在就执行 并返回true
*
* @param key
* @param value
* @return true成功 false失败
*/
public Boolean setNx(String key, Object value) {
return redisTemplate.opsForValue().setIfAbsent(key, value);
}
/**
* 如果key已存在就不执行,并返回false 不存在就执行 并返回true
*
* @param key
* @param value
* @return true成功 false失败
*/
public Boolean setNx(String key, Object value, long time) {
return redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);
}
/**
* 如果key已存在就执行,并返回true 不存在就不执行 并返回false
*
* @param key
* @param value
* @return true成功 false失败
*/
public Boolean setXx(String key, Object value) {
return redisTemplate.opsForValue().setIfPresent(key, value);
}
/**
* 如果key已存在就执行,并返回true 不存在就不执行 并返回false
*
* @param key
* @param value
* @return true成功 false失败
*/
public Boolean setXx(String key, Object value, long time) {
return redisTemplate.opsForValue().setIfPresent(key, value, time, TimeUnit.SECONDS);
}
/**
* 递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
*
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
*
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// ============================set=============================
/**
* 根据key获取Set中的所有值
*
* @param key 键
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
*
* @param key 键
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
*
* @param key 键
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
*
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
- redis的windows配置简单介绍
找到redis.windows.conf中进行配置
protected-mode no // 改为no 不开启保护模式
port 6379 //redis端口号
daemonize yes // 开启守护线程 (redis关闭的时候也照样运行)
requirepass **** //设置redis的访问密码
#bind 127.0.0.1 只能本机访问 (关闭)
使用redis锁
导包
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.15.4</version>
</dependency>
yml配置
spring:
redis:
port: 6379 #redis的端口号默认端口是6379
password: 123456 #密码
host: redis
timeout: 5000
database: 3
引入配置
package com.itllc.config.RedisConfig;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author lilinchun
* @date 2022/7/7 0007 11:31
*/
@Configuration
@EnableCaching
public class RedissonConfig {
@Value("${spring.redis.host}")
String REDIS_HOST;
@Value("${spring.redis.port}")
String REDIS_PORT;
@Value("${spring.redis.password}")
String REDIS_PASSWORD;
@Value("${spring.redis.database}")
int REDIS_DATABASE;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
SingleServerConfig r = config.useSingleServer();
r.setAddress("redis://" + REDIS_HOST + ":" + REDIS_PORT)
.setDatabase(REDIS_DATABASE)
.setConnectionMinimumIdleSize(5)
.setConnectionPoolSize(10);
if (!StringUtils.isEmpty(REDIS_PASSWORD)) {
r.setPassword(REDIS_PASSWORD);
}
return Redisson.create(config);
}
}
测试用例
/**
* redis消息发送
*
* @param message
*/
@GetMapping(value = "/redisLock")
@ApiOperation("redis锁测试")
public Result<Boolean> redisLock(@NotBlank @ApiParam(value = "发送的消息",required = true) @RequestParam("message") String message) {
String key = "redis_lock";
RLock lock = redissonClient.getLock(key);//获取锁
lock.lock();//加锁
try {
//业务放到try中
String res = (String) redisTemplate.opsForValue().get("goods:001");
int count = res == null ? 0 :Integer.parseInt(res);
if(count > 0){
int realCount = count - 1;//减库存
//将库存设置到数据库
redisTemplate.opsForValue().set("goods:001",String.valueOf(realCount));
System.out.println("剩余库存:"+realCount+",服务的端口:");
}else{
System.out.println("库存没有了");
}
} finally {
if(lock.isLocked() && lock.isHeldByCurrentThread()){
lock.unlock();//解锁
}
}
return new Result<>(true);
}
redis注解缓存
平时大家使用redis一般都是直接存储key,value.
spring全家桶肯定帮大家想到了这一点.可以让大家方便的使用注解操作redis节省代码量.
总结:总共有三种方式,底层利用了spring的aop,并且方法返回的对象一定要实现序列化
- @Cacheable:注解于方法上,第一次会把后面的cacheNames+key 拼接为key,把返回值序列化后作为value set到redis中去.后面再一次访问相同的key的时候就直接从redis中取值了,不会再访问这个方法
@Override
@Cacheable(cacheNames = "product",key = "#id")
public ProductInfo findOne(String id) {
return productInfoRepository.findById(id).orElse(null);
}
- @CachePut:每次都会把方法的返回值序列化之后set到redis中去(每次都会执行方法),即更新这个key对应的值
@Override
@CachePut(cacheNames = "product",key = "#productId")
public ProductInfo onSale(String productId) {
ProductInfo productInfo = this.findOne(productId);
if(null == productInfo){
throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
}
if(productInfo.getProductStatusEnum().getCode() == ProductStatusEnum.UP.getCode()){
log.warn("[商品上架处理]-----商品已经是上架状态了,这里直接返回原ProductInfo={}",productInfo);
}else {
productInfo.setProductStatus(ProductStatusEnum.UP.getCode());
productInfo = this.save(productInfo);
}
return productInfo;
}
- @CacheEvict:这个比较好理解,就是从redis中把这个key删除了
@Override
@CacheEvict(cacheNames = "product",key = "#productInfo.productId")
public ProductInfo save(ProductInfo productInfo) {
return productInfoRepository.save(productInfo);
}
这里的key其实可以不写,比如上面的@CacheEvict中不写的话就会把参数默认为key,即下面的productInfo对象
一次驱逐多个redis的key
@Caching(evict={
@CacheEvict(value = Cache.CONSTANT, key = "'" + CacheKey.SINGLE_ROLE_NAME + "'+#roleId"),
@CacheEvict(value = Cache.CONSTANT, key = "'" + CacheKey.ROLES_NAME + "'+#roleId"),
@CacheEvict(value = Cache.CONSTANT, key = "'" + CacheKey.SINGLE_ROLE_NAME + "'+#roleId")
})
public ResponseData remove(@RequestParam Long roleId) {
………………
}
- 可以加在方法上使用@Cacheable set value到redis
使用@Cacheable后,第一次会把后面的cacheNames+key 拼接为key,把返回值序列化后作为value set到redis中去.后面再一次访问相同的key的时候就直接从redis中取值了,不会再访问这个方法,也就不会再从数据库中取值了
可以把方法中的参数拼到key上,在这个方法运行完后会把这个方法的返回值根据@Cacheable注解中的cacheNames+key拼接后的值为key,set到redis中取,下次再访问这个key的时候直接从redis中取数据,不用去mysql查找一遍了
- 使用condition,对传入的参数进行,筛选只允许符合条件的请求set到redis中
对于现实的需求,肯定有些时候是异常请求,是不需要缓存到redis中的,这里我们也可以使用condition加上判断,判断通过的时候才允许缓存到redis
- 有根据请求筛选,那么自然也就有根据方法的结果筛选的,根据结果筛选可以使用unless
@Cacheable中,unless参数的作用是:函数返回值符合表达式条件的,veto(否决)、不缓存
换句话说,函数返回值符合条件的排除掉、只缓存其余不符合条件的 - 若是想要某种条件下才缓存,那么可以在el表达式中对其他情况取反就行了
例如,想要返回结果中productId = 1的,那么可以这样写
@Cacheable(cacheNames = “product111”,key = “#productInfo.productId”, unless = “!#result.productId.equals(‘1’)”)
把结果中不等于1的排除掉,那么剩下的就是等于1了
这里可能有点绕,因为unless自动在最外面取了个反,所以要双重否定
简单说就是对你想要的结果取反,unless自己外面有取反!!2个取反就还是原先的结果 - 使用@CacheConfig注解可以让多个方法使用统一的cacheNames
如果在同一个类中,要使用redis缓存的每个方法中都要写cacheNames是不是觉得很麻烦,可以使用@CacheConfig(cacheNames = “product”),为下面的注解默认使用上面这个CacheConfig中定义的cacheNames
这个和css中的作用域一样,如果方法上的注解有自己定义的cacheNames,那么最后生效的还是方法上自己定义的cacheNames,并不会强行使用类上CacheConfig定义的cacheNames
详情:redis注解缓存原文
redis缓存
新增RedisTemplate封装工具类 : 最全的 基于 RedisTemplate 封装的 RedisUtils 工具类
Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。
Redis的String数据结构
set void set(K key, V value);
redisTemplate.opsForValue().set("num","123");
redisTemplate.opsForValue().get("num") 输出结果为123
set void set(K key, V value, long timeout, TimeUnit unit);
redisTemplate.opsForValue().set("num","123",10, TimeUnit.SECONDS);
redisTemplate.opsForValue().get("num")设置的是10秒失效,十秒之内查询有结果,十秒之后返回为null
set void set(K key, V value, long offset);
覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始
template.opsForValue().set("key","hello world");
template.opsForValue().set("key","redis", 6);
System.out.println("***************"+template.opsForValue().get("key"));
结果:***************hello redis
get V get(Object key);
template.opsForValue().set("key","hello world");
System.out.println("***************"+template.opsForValue().get("key"));
结果:***************hello world
getAndSet V getAndSet(K key, V value);
设置键的字符串值并返回其旧值
template.opsForValue().set("getSetTest","test");
System.out.println(template.opsForValue().getAndSet("getSetTest","test2"));
结果:test
append Integer append(K key, String value);
如果key已经存在并且是一个字符串,则该命令将该值追加到字符串的末尾。如果键不存在,则它被创建并设置为空字符串,因此APPEND在这种特殊情况下将类似于SET。
template.opsForValue().append("test","Hello");
System.out.println(template.opsForValue().get("test"));
template.opsForValue().append("test","world");
System.out.println(template.opsForValue().get("test"));
Hello
Helloworld
size Long size(K key);
返回key所对应的value值得长度
template.opsForValue().set("key","hello world");
System.out.println("***************"+template.opsForValue().size("key"));
***************11
Redis的List数据结构
Long size(K key);
返回存储在键中的列表的长度。如果键不存在,则将其解释为空列表,并返回0。当key存储的值不是列表时返回错误。
System.out.println(template.opsForList().size("list"));
6
Long leftPush(K key, V value);
将所有指定的值插入存储在键的列表的头部。如果键不存在,则在执行推送操作之前将其创建为空列表。(从左边插入)
template.opsForList().leftPush("list","java");
template.opsForList().leftPush("list","python");
template.opsForList().leftPush("list","c++");
返回的结果为推送操作后的列表的长度
1
2
3
Long leftPushAll(K key, V… values);
批量把一个数组插入到列表中
String[] strs = new String[]{"1","2","3"};
template.opsForList().leftPushAll("list",strs);
System.out.println(template.opsForList().range("list",0,-1));
[3, 2, 1]
Long rightPush(K key, V value);
将所有指定的值插入存储在键的列表的头部。如果键不存在,则在执行推送操作之前将其创建为空列表。(从右边插入)
template.opsForList().rightPush("listRight","java");
template.opsForList().rightPush("listRight","python");
template.opsForList().rightPush("listRight","c++");
1
2
3
Long rightPushAll(K key, V… values);
String[] strs = new String[]{"1","2","3"};
template.opsForList().rightPushAll("list",strs);
System.out.println(template.opsForList().range("list",0,-1));
[1, 2, 3]
void set(K key, long index, V value);
在列表中index的位置设置value值
System.out.println(template.opsForList().range("listRight",0,-1));
template.opsForList().set("listRight",1,"setValue");
System.out.println(template.opsForList().range("listRight",0,-1));
[java, python, oc, c++]
[java, setValue, oc, c++]
Long remove(K key, long count, Object value);
从存储在键中的列表中删除等于值的元素的第一个计数事件。
计数参数以下列方式影响操作:
count> 0:删除等于从头到尾移动的值的元素。
count <0:删除等于从尾到头移动的值的元素。
count = 0:删除等于value的所有元素。
System.out.println(template.opsForList().range("listRight",0,-1));
template.opsForList().remove("listRight",1,"setValue");//将删除列表中存储的列表中第一次次出现的“setValue”。
System.out.println(template.opsForList().range("listRight",0,-1));
[java, setValue, oc, c++]
[java, oc, c++]
V index(K key, long index);
根据下表获取列表中的值,下标是从0开始的
System.out.println(template.opsForList().range("listRight",0,-1));
System.out.println(template.opsForList().index("listRight",2));
[java, oc, c++]
c++
V leftPop(K key);
弹出最左边的元素,弹出之后该值在列表中将不复存在
System.out.println(template.opsForList().range("list",0,-1));
System.out.println(template.opsForList().leftPop("list"));
System.out.println(template.opsForList().range("list",0,-1));
[c++, python, oc, java, c#, c#]
c++
[python, oc, java, c#, c#]
V rightPop(K key);
弹出最右边的元素,弹出之后该值在列表中将不复存在
System.out.println(template.opsForList().range("list",0,-1));
System.out.println(template.opsForList().rightPop("list"));
System.out.println(template.opsForList().range("list",0,-1));
[python, oc, java, c#, c#]
c#
[python, oc, java, c#]
Redis的Hash数据结构
Long delete(H key, Object… hashKeys);
删除给定的哈希hashKeys
System.out.println(template.opsForHash().delete("redisHash","name"));
System.out.println(template.opsForHash().entries("redisHash"));
1
{class=6, age=28.1}
Boolean hasKey(H key, Object hashKey);
确定哈希hashKey是否存在
System.out.println(template.opsForHash().hasKey("redisHash","666"));
System.out.println(template.opsForHash().hasKey("redisHash","777"));
true
false
HV get(H key, Object hashKey);
从键中的哈希获取给定hashKey的值
System.out.println(template.opsForHash().get("redisHash","age"));
26
Set keys(H key);
获取key所对应的散列表的key
System.out.println(template.opsForHash().keys("redisHash"));
//redisHash所对应的散列表为{class=1, name=666, age=27}
[name, class, age]
Long size(H key);
获取key所对应的散列表的大小个数
System.out.println(template.opsForHash().size("redisHash"));
//redisHash所对应的散列表为{class=1, name=666, age=27}
3
void putAll(H key, Map<? extends HK, ? extends HV> m);
使用m中提供的多个散列字段设置到key对应的散列表中
Map<String,Object> testMap = new HashMap();
testMap.put("name","666");
testMap.put("age",27);
testMap.put("class","1");
template.opsForHash().putAll("redisHash1",testMap);
System.out.println(template.opsForHash().entries("redisHash1"));
{class=1, name=jack, age=27}
void put(H key, HK hashKey, HV value);
设置散列hashKey的值
template.opsForHash().put("redisHash","name","666");
template.opsForHash().put("redisHash","age",26);
template.opsForHash().put("redisHash","class","6");
System.out.println(template.opsForHash().entries("redisHash"));
{age=26, class=6, name=666}
List values(H key);
获取整个哈希存储的值根据密钥
System.out.println(template.opsForHash().values("redisHash"));
[tom, 26, 6]
Map<HK, HV> entries(H key);
获取整个哈希存储根据密钥
System.out.println(template.opsForHash().entries("redisHash"));
{age=26, class=6, name=tom}
Cursor<Map.Entry<HK, HV>> scan(H key, ScanOptions options);
使用Cursor在key的hash中迭代,相当于迭代器。
Cursor<Map.Entry<Object, Object>> curosr = template.opsForHash().scan("redisHash",
ScanOptions.ScanOptions.NONE);
while(curosr.hasNext()){
Map.Entry<Object, Object> entry = curosr.next();
System.out.println(entry.getKey()+":"+entry.getValue());
}
age:27
class:6
name:666
Redis的Set数据结构
Long add(K key, V… values);
无序集合中添加元素,返回添加个数
也可以直接在add里面添加多个值 如:template.opsForSet().add(“setTest”,“aaa”,“bbb”)
String[] strs= new String[]{"str1","str2"};
System.out.println(template.opsForSet().add("setTest", strs));
2
Long remove(K key, Object… values);
移除集合中一个或多个成员
String[] strs = new String[]{"str1","str2"};
System.out.println(template.opsForSet().remove("setTest",strs));
2
V pop(K key);
移除并返回集合中的一个随机元素
System.out.println(template.opsForSet().pop("setTest"));
System.out.println(template.opsForSet().members("setTest"));
bbb
[aaa, ccc]
Boolean move(K key, V value, K destKey);
将 member 元素从 source 集合移动到 destination 集合
template.opsForSet().move("setTest","aaa","setTest2");
System.out.println(template.opsForSet().members("setTest"));
System.out.println(template.opsForSet().members("setTest2"));
[ccc]
[aaa]
Long size(K key);
无序集合的大小长度
System.out.println(template.opsForSet().size("setTest"));
1
Set members(K key);
返回集合中的所有成员
System.out.println(template.opsForSet().members("setTest"));
[ddd, bbb, aaa, ccc]
Cursor scan(K key, ScanOptions options);
遍历set
Cursor<Object> curosr = template.opsForSet().scan("setTest", ScanOptions.NONE);
while(curosr.hasNext()){
System.out.println(curosr.next());
}
ddd
bbb
aaa
ccc
Redis的ZSet数据结构
Boolean add(K key, V value, double score);
新增一个有序集合,存在的话为false,不存在的话为true
System.out.println(template.opsForZSet().add("zset1","zset-1",1.0));
true
Long add(K key, Set<TypedTuple> tuples);
新增一个有序集合
ZSetOperations.TypedTuple<Object> objectTypedTuple1 = new DefaultTypedTuple<>("zset-5",9.6);
ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<>("zset-6",9.9);
Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>();
tuples.add(objectTypedTuple1);
tuples.add(objectTypedTuple2);
System.out.println(template.opsForZSet().add("zset1",tuples));
System.out.println(template.opsForZSet().range("zset1",0,-1));
[zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]
Long remove(K key, Object… values);
从有序集合中移除一个或者多个元素
System.out.println(template.opsForZSet().range("zset1",0,-1));
System.out.println(template.opsForZSet().remove("zset1","zset-6"));
System.out.println(template.opsForZSet().range("zset1",0,-1));
[zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]
1
[zset-1, zset-2, zset-3, zset-4, zset-5]
Long rank(K key, Object o);
返回有序集中指定成员的排名,其中有序集成员按分数值递增(从小到大)顺序排列
System.out.println(template.opsForZSet().range("zset1",0,-1));
System.out.println(template.opsForZSet().rank("zset1","zset-2"));
[zset-2, zset-1, zset-3, zset-4, zset-5]
0 //表明排名第一
Set range(K key, long start, long end);
通过索引区间返回有序集合成指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列
System.out.println(template.opsForZSet().range("zset1",0,-1));
[zset-2, zset-1, zset-3, zset-4, zset-5]
Long count(K key, double min, double max);
通过分数返回有序集合指定区间内的成员个数
System.out.println(template.opsForZSet().rangeByScore("zset1",0,5));
System.out.println(template.opsForZSet().count("zset1",0,5));
[zset-2, zset-1, zset-3]
3
Long size(K key);
获取有序集合的成员数,内部调用的就是zCard方法
System.out.println(template.opsForZSet().size("zset1"));
6
Double score(K key, Object o);
获取指定成员的score值
System.out.println(template.opsForZSet().score("zset1","zset-1"));
2.2
Long removeRange(K key, long start, long end);
移除指定索引位置的成员,其中有序集成员按分数值递增(从小到大)顺序排列
System.out.println(template.opsForZSet().range("zset2",0,-1));
System.out.println(template.opsForZSet().removeRange("zset2",1,2));
System.out.println(template.opsForZSet().range("zset2",0,-1));
[zset-1, zset-2, zset-3, zset-4]
2
[zset-1, zset-4]
Cursor<TypedTuple> scan(K key, ScanOptions options);
遍历zset
Cursor<ZSetOperations.TypedTuple<Object>> cursor = template.opsForZSet().scan("zzset1", ScanOptions.NONE);
while (cursor.hasNext()){
ZSetOperations.TypedTuple<Object> item = cursor.next();
System.out.println(item.getValue() + ":" + item.getScore());
}
zset-1:1.0
zset-2:2.0
zset-3:3.0
zset-4:6.0
引用链接:https://lionli.blog.csdn.net/article/details/82011670?spm=1001.2014.3001.5506
设置过期时间:
redisTemplate.opsForSet().getOperations().expire(key, 5, TimeUnit.HOURS);
redisTemplate.opsForHash().getOperations().expire(key, 5, TimeUnit.HOURS);