1-String:字符串
2-List:列表
3-Hash:哈希字典
4-Set:集合
5-Sorted Set:有序集合
存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型
存储数据的格式:一个存储空间保存一个数据
存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用(但是仍是字符串)
SET key value 设置key=value
GET key 获得键key对应的值
SETNX key value 设置键的值,只有当该键不存在
SETEX key seconds value 键到期时设置值
MSET key value [key value...] 设置多个键和多个值
MSETNX key value [key value...] 设置多个键多个值,只有在当没有按键的存在时
PSETEX key milliseconds value 设置键的毫秒值和到期时间
DEL key 如果存在删除键
大型企业级应用中,常见分表操作,使用多张表存储同类型数据,但是对应的主键id必须保证统一性,不能重复。
Oracle数据库具有sequence设定,可以解决该问题,但是mysql数据库并没有类似的机制,如何解决?
设置数值数据增加指定范围的值
incr key //自增1
incrby key increment //增加指定数值
incrbyfloat key increment //增加一个浮点数
设置数值数据减少指定范围的值
decr key //自减1
decrby key increment //减少指定数值
给用户设置一个唯一的id,并为其设置一个有效时长,当时间已经超过设定时间后将id删除。
redis 控制数据的生命周期,通过数据是否失效控制业务行为,适用于所有具有时效性限定控制的操作:
setex key seconds value //增加、修改键值对并为其设定生命周期
psetex key milliseconds value //功能与上面一直,秒的单位不同
例如:setex name 10 time,超过10s以后再get name就发现没有这个值了
主页高频访问信息显示控制,例如微博大V主页显示粉丝数与微博数量,这些数据就是热度数据,不断发生变化,这些数据如何放入redis?
(1)实现方式一:在redis中为大V用户设定用户信息,以用户主键和属性值为key,后台设定时间定时刷新即可
(2)在redis中以json格式存储大V用户,定时刷新
set user: id :5765898790 {id:5765898790,focuss:3050,fans:117492300,blogs:117744}
数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分
需要的存储数据:一个存储空间保存多个数据,且通过数据可以体现进入顺序
list类型:保存多个数据,底层使用双向链表存储结构实现
LPUSH key value1 [value2] 在前面加上一个或多个值的列表
LLEN key 获取列表的长度
RPUSH key value1 [value2] 添加一个或多个值到列表
LRANGE key start stop 从一个列表获取各种元素
RPOP key 取出并获取列表中的最后一个元素
LPOP key 获取并取出列表中的第一个元素
lindex key index 查询第i个元素
blpop key1 [key2] timeout
brpop key1 [key2] timeout
阻塞式获取,在规定时间内获取这个值,规定时间内如果还没有的时候可以等,直到有值就可以获取到获取超时获取为空。
开两个客户端,一个设置15s内获取list1中的值,此时list1位空一直等待(阻塞),在15秒内另一个客户端存入到list1中数据,此时就被获取到。
微信朋友圈点赞,要求按照点赞顺序显示点赞好友信息。
如果取消点赞,移除对应好友信息。
移除指定数据
lrem key count value //count为移除的数量,value为移除哪个值
点赞的时候,使用rpush往list尾部按顺序加入数据
移除好友的时候,使用lrem daqiao 2 zhangfei 来从list中移除
(1)list 中保存的数据都是string类型的,数据总容量式是有限的,最多232-1个元素(4294967295)
(2)list具有索引的概念,但是操作数据时候通常以队列的形式进行入队出队操作,或以栈的形式进入栈出栈的操作
(3)获取全部数据操作结束索引设置为-1
(4)list 可以对数据进行分页操作,通过第一页的信息来自list,第2页及更多的信息通过数据库的形式加载
(1)twitter、新浪微博、腾讯微博中个人用于的关注列表需要按照用户的关注顺序进行展示,粉丝列表需要将最近关注的粉丝列在前面
(2)新闻、资讯类网站如何将最新的新闻或资讯按照发生的事件顺序展示
(3)企业运营过程中,系统将产生出大量的运营数据,如何保障堕胎服务器操作日志的统一顺序输出?
(1)依赖list的数据具有顺序的特征对信息进行管理
(2)使用队列模型解决多路信息汇总合并的问题
(3)使用栈模型解决最新消息的问题
String类型存储的困惑
对象类数据的存储如果具有较为频繁的更新需求,操作会显得笨重,存容易,改麻烦。
为了区别与Redis中的键值对的称呼,hash中的键成为field,而key特征Redis的键。
hash类型
新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息
需要的内存结构:一个存储空间保存多少个键值对数据
hash类型:底层使用哈希表结构实现数据存储
HSET key field value 设置对象指定字段的值
HGET key field 获取对象中该field属性域的值
HGETALL key 获取对象的所有属性域和值
HKEYS key 获取对象的所有属性字段
HVALS key 获取对象的所有属性值
HLEN key 获取对象的所有属性字段的总数
HSETNX key field value 只在对象不存在指定的字段时才设置字段的值
hdel key field1 [field2] 删除数据
hmset key field1 value1 field2 calue2 添加/修改多个数据
hmget key field1 field2 … 获取多个数据
hexists key field 获取哈希表中是否存在指定的字段
获取哈希表中所有的字段名和字段值
hkeys key //字段名
hvals key //字段值
设置指定字段的数值数据增加指定范围的值
hincrby key field increment //指定数值增长指定的数
hincrbyfloat key field increment
案例:user1年龄增加2岁,曾增加0.5岁
(1)hash类型下的value只能存储字符串,不允许存储其他类型数据,不存在嵌套现象。如果数据未获取到,对应的值为(nil)
(2)每个hash可以存储232-1个键值对
(3)hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计不是为了存储大量对象的,切记不可滥用,更不可以将hash作为对象列表使用
(4)hgetall操作可以获取全部属性,如果内部fiekd过多,遍历整体数据效率就会很低,有可能成为数据访问瓶颈。
电商网站购物车的设计和实现
(1)思路
(2)代码案例
例如创建一个购物车:
(3)优化思路
当前仅仅是将数据存储到redis中,并没有起到加速的所用,因为我们仅仅查询到了用户的id和商品的id,显示的时候显示的用户名和商品的名称,商品信息还需要二次查询数据库。
1-每条购物车中的商品记录保存成两条field
2-field1 专用于保存购买数量
命名格式:商品id:nums
保存数据:数值
3-field2 专用于保存购物车中显示的信息,包含文字描述,图片地址,所属商家信息等等
命名格式:商品id:info
保存数据:json
但是出现很多用户都将同一个商品假如购物车,就会出现大量的重复信息,例如商品信息重复:
因此我们可以将商品的信息单独的保存成一个哈希。
(4)创建数据,如果有则不再创建,如果没有则创建
hsetnx key field value
双11活动日,销售手机充值卡的上级啊对移动、联通、典型的30元、50元、100元商品退出抢购活动,每种商品抢购上限1000张
(1)以商家id作为key
(2)将参与抢购的商品id作为field
(3)将参与抢购的商品数量作为对应的value
(4)抢购时使用降至的方式控制产品数量
(1)新的存储需求:存储大量的数据,在查询方面提供更高的效率
(2)需要的存储结构:能够保存大量的数据,搞笑的内部存储机制,便于查询
(3)set类型:与hash存储结构完全相同,仅存储键,不存储值(nil),并且值式不允许重复的。也就是只有键没有值的hash
SADD key member [member ...] 添加一个或者多个元素到集合(set)里
SCARD key 获取集合里面的元素数量
SMEMBERS key 获取集合里面的所有key
SPOP key [count] 获取并删除一个集合里面的元素
srem key member1 [member2] 删除数据
sismember key member 判断集合中是否包含指定数据
srandmember key [count] 随机获取集合中指定数量的数据
每位用户首次使用进入头条时候会设置3项爱好的内容,但是后期为了增加用户的活跃度,兴趣点,必须让用户对其他信息类别逐渐产生兴趣,增加客户留存度,如何实现?
(1)系统分析出各个分类的最新或最热点信息条目并组织成set集合
(2)随机挑选其中部分信息
(3) 配合用户关注信息分类中的热点信息组织展示的全信息集合
redis应用于随机推荐类信息检索,例如热点歌单推荐,热点新闻推荐,热点旅游线路,应用APP推荐,大V推荐等。
(1)新浪微博为了增加用户热度,提高用户留存性,需要微博用户在关注更多的人,以此获得更多的信息或热门话题,如何提高用户关注他人的总量?
(2)qq新用户入网年龄越来越低,这些用户的朋友圈交际圈非常小,往往集中在一所学校甚至一个班级中,如何帮助用户快速积累好友用户带来更多的活跃度?
(3)微信公众号是微信信息流通的渠道之一,增加用户关注的公众号成为提高用户活跃度的一种方式,如何帮助用户积累更多关注的公众号?
(4)美团外卖为了提升成单量,必须帮助用户挖掘没事需求,如何推荐给用户最合适自己的美食?
(1)求两个集合的交、并、差集
sinter key1 [key2] //交集
sunion key1 [key2] //并集
sdiff key1 [key2] //差集(key1有但是key2没有的)
(2)求两个集合的交、并、差集并存储到指定集合中
sinterstore destination key1 [key2]
sunionstore destination key1 [key2]
sdiffstore destination key1 [key2]
(3)将指定数据从原始集合移动到目标集合中
smove source destination member
(1)显示共同关注(一度)
(2)显示共同好友(一度)
(3)由用户A出发,获取到好友用户B的好友信息列表(一度)
(4)由用户A出发,获取到好友用户B的购物清单列表(二度)
(5)由用户A出发,获取到好友用户B的游戏充值列表(二度)
set类型不允许数据重复,如果添加的数据在set中已经存在,将只保留一份
set虽然与hash的存储结构相同,但是无法启用hash中存储值的空间
集团公司共具有12000名员工,内部oa系统中具有700多个角色,3000多个业务操作,23000多种数据,每位员工具有一个或多个角色,如何快速进行业务操作的权限校验
依赖set集合数据不重复的特征,依赖set集合hash存储结构特征完成数据过滤与快速查询
(1)根据用户id获取用户所有角色
(2)根据用户所有角色获取用户所有操作权限放入set集合
(3)根据用户所有觉得获取用户所有数据全选放入set集合
针对不同的统计类型有不同的数据存储方式:
(1)利用set集合的数据去重特征,记录各种访问数据
(2)建立string类型数据,利用incr统计日访问量(PV)
(3)建立set模型,记录不同cookie数量(UV)
(4)建立set模型,记录不用IP数量(IP)
(1)基于经营战略设定问题用户发现、鉴别规则
(2)周期性更行满足规则的用户黑名单,加入set集合
(3)用户行为信息达到后与黑名单进行比比对,确认行为去向
(4)黑名单过滤IP地址:应用于开放游客访问权限的信息源
(5)黑名单过滤设备信息:应用于限定访问设备的信息源
(6)黑名单过滤用户:应用于基于访问权限的信息源
(1)新的存储需求:根据排序有利于数据的有效显示,需要提供一种可以根据自身特征进行排序的方式。
(2)需要的存储结构:新的存储模型,可以保存可排序的数据。
(3)sorted_set类型:在set的存储结构基础上添加可排序字段。
score只存储其顺序。
ZADD key score1 member1 [score2 member2] 添加一个或多个成员到有序集合,或者如果它已经存在更新其分数
ZCARD key 得到的有序集合成员的数量
ZCOUNT key min max 计算一个有序集合成员与给定值范围内的分数
ZREM key member [member ...] 从有序集合中删除一个或多个成员,不存在的成员将被忽略
zrange key start stop [WITHSCORES]//按照从小到大的顺序,加上WITHSCORES,就会带上scores一起显示
zrevrange key start stop [WITHSCORES]//按照从大到小的顺序
zrangebyscore key min max [WITHSCORES] [LIMIT] //查询scores在某个范围内的值
zrevrangebyscore key max min [WITHSCORES] //查询key某个索引范围内的值
条件删除
zremrangebyrank key start stop
zremrangebyscore key min max
获取集合数据总量
zcard key //获取总量
zcount key min max //获取某一个范围的总量
集合交、并存储操作
zinterstore destination numkeys key [key …] //求和
zunionstore destination numkeys key [key …]
(1)min与max用于限定搜索查询的条件
(2)start与stop用于限定查询范围,作用于索引,表示开始和结束索引
(3)offset与count用于限定查询范围,作用于查询结果,表示开始位置和数据总量
(1)获取数据对应的索引(排名)
zrank key member //正数第几位
zrevrank key member //倒数第几位
(2)score 值获取与修改
zscore key member //获取
zincrby key increment member //score递增 increment
(1)score 保存的数据存储空间是64位
(2)score保存的数据也可以是一个双精度的double值,基于双精度浮点数的特征,可能会丢失精度,使用时侯要慎重
(3)sorted_set底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被反复覆盖,保留最后一次修改的结果
(1)对于基于时间线限定的任务处理,将处理时间记录为score值,利用排序功能区分处理的先后顺序
(2)记录下一个要处理的事件,当对比系统时间发现当然仍后到期后移除redis中的记录,并记录下一个要处理的时间
(3)当新任务加入时,判定并更新当前下一个要处理的任务时间
(4)为提升sorted_set的性能,通常将任务根据特征存储成若干个sorted_set.例如1小时内,1天内,年度等,操作时逐渐提升,将即将操作的若干个任务纳入到1小时内处理队列中
(5)time命令获取当前系统时间
如何实现这个每分钟只能调用10次呢?
(1)设计计数器,记录调用次数,用于控制业务执行次数。以用户id作为key,使用此时作为value
(2)在调用前获取次数,判断是否超过限定次数,不超过次数的情况下,每次调用计数+1,业务调用失败,不递增
(3)为了计数器设置生命周期为指定周期,例如10次/分钟,自动清空周期内使用次数。
利用可以存储的最大值是9223372036854775807,超过这个值就会抛出异常的特性。假如一分钟只能访问5次,可以将初始值设置为9223372036854775802,每次访问都加1,访问5次后这个数就会溢出异常。
(1)依赖list的数据具有顺序的特征对消息进行管理,将list结构作为栈使用
对指定与普通会话分别创建独立的list分别管理
(2)当某个list中接收到用户消息后,将消息发送方的id从list的一侧加入list(此处设定左侧)
(3)多个相同id发出的消息反复入栈会出现问题,在入栈之前无论是否具有当前id对应得消息,先删除对应id
(4)推送消息时先推送顶置会话list,再推送普通会话list,推送完成的list清除所有数据
(5)消息的数量,也就是微信用户对话数量采用计数器的思想另行记录,伴随list操作同步更新
package com.how2java;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
/**
* 基于spring和redis的redisTemplate工具类
* 针对所有的hash 都是以h开头的方法
* 针对所有的Set 都是以s开头的方法 不含通用方法
* 针对所有的List 都是以l开头的方法
*/
public class RedisUtil {
private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//=============================common============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
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);
}
/**
* 普通缓存放入
* @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;
}
}
/**
* 递增
* @param key 键
* @param by 要增加几(大于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 by 要减少几(小于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 值
* @param time 时间(秒)
* @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 值
* @param time 时间(秒)
* @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;
}
}
}