赵计刚
每天进步一点点

注意:本章代码是在上一章的基础上进行添加修改,上一章链接《第九章 企业项目开发--分布式缓存Redis(1)

上一章说了ShardedJedisPool的创建过程,以及redis五种数据结构的第一种String类型的常用缓存操作方法。下面说余下的四种:

  • list(有序列表)
  • set(无序集合)
  • sorted set(有序集合)
  • hash

 

1、ssmm0-cache

1.1、RedisListUtil(有序列表工具类)

  1 package com.xxx.cache.redis;
  2 
  3 import java.util.List;
  4 
  5 import redis.clients.jedis.ShardedJedis;
  6 
  7 /**
  8  * list缓存操作类
  9  * 1、顺序为插入list的顺序
 10  * 2、允许存放重复元素
 11  * 3、可用作模拟队列(queue)、堆栈(stack),支持双向操作(L--首部或者R--尾部)
 12  * 4、index从0开始 -1表示结尾  -2表示倒数第二个
 13  * 5、API中的 start end参数 都是包前也包后的
 14  */
 15 public class RedisListUtil extends RedisBaseUtil{
 16     
 17     /***************************添加缓存*****************************/
 18     /**
 19      * 从左边(首部)加入列表
 20      * 注意:
 21      * 1、可以一次性入队n个元素(这里使用了不定参数,当然可以换做数组)
 22      * 2、不定参数必须放在所有参数的最后边
 23      * 3、左边入队,相当于在队头插入元素,则之后的元素都要后移一位;而右边入队的话元素直接插在队尾,之前的元素的索引不变
 24      * 4、没有从list中获取指定value的运算
 25      */
 26     public static void lpush(String list, String... values){
 27         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 28         ShardedJedis jedis = null;
 29         try {
 30             jedis = getJedis();//获取jedis实例
 31             if(jedis==null){
 32                 broken = true;
 33                 return;
 34             }
 35             /*
 36              * lpush(String key, String... strings);
 37              * 返回push之后的list中包含的元素个数
 38              */
 39             jedis.lpush(list, values);
 40         } catch (Exception e) {
 41             broken = true;
 42         }finally{
 43             returnJedis(jedis, broken);
 44         }
 45     }
 46     
 47     /**
 48      * 从左边(首部)加入列表
 49      * 并指定列表缓存过期时间
 50      */
 51     public static void lpush(String list, int expire, String... values){
 52         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 53         ShardedJedis jedis = null;
 54         try {
 55             jedis = getJedis();//获取jedis实例
 56             if(jedis==null){
 57                 broken = true;
 58                 return;
 59             }
 60             /*
 61              * lpush(String key, String... strings);
 62              * 返回push之后的list中包含的元素个数
 63              */
 64             jedis.lpush(list, values);
 65             jedis.expire(list, expire);//为该list设置缓存过期时间
 66         } catch (Exception e) {
 67             broken = true;
 68         }finally{
 69             returnJedis(jedis, broken);
 70         }
 71     }
 72     
 73     /**
 74      * 从右边(尾部)加入列表
 75      */
 76     public static void rpush(String list, String... values){
 77         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 78         ShardedJedis jedis = null;
 79         try {
 80             jedis = getJedis();//获取jedis实例
 81             if(jedis==null){
 82                 broken = true;
 83                 return;
 84             }
 85             jedis.rpush(list, values);
 86         } catch (Exception e) {
 87             broken = true;
 88         }finally{
 89             returnJedis(jedis, broken);
 90         }
 91     }
 92     
 93     /**
 94      * 从右边(尾部)加入列表
 95      * 并设置缓存过期时间
 96      */
 97     public static void rpush(String list, int expire, String... values){
 98         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 99         ShardedJedis jedis = null;
100         try {
101             jedis = getJedis();//获取jedis实例
102             if(jedis==null){
103                 broken = true;
104                 return;
105             }
106             jedis.rpush(list, values);
107             jedis.expire(list, expire);//设置缓存过期时间
108         } catch (Exception e) {
109             broken = true;
110         }finally{
111             returnJedis(jedis, broken);
112         }
113     }
114     
115     /**
116      * 设置list中index位置的元素
117      * index==-1表示最后一个元素
118      */
119     public static void lSetIndex(String list, long index, String value){
120         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
121         ShardedJedis jedis = null;
122         try {
123             jedis = getJedis();//获取jedis实例
124             if(jedis==null){
125                 broken = true;
126                 return;
127             }
128             jedis.lset(list, index, value);
129         } catch (Exception e) {
130             broken = true;
131         }finally{
132             returnJedis(jedis, broken);
133         }
134     }
135     
136     /***************************获取缓存*****************************/
137     /**
138      * 从左边(首部)出列表
139      */
140     public static String lpop(String list){
141         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
142         ShardedJedis jedis = null;
143         try {
144             jedis = getJedis();//获取jedis实例
145             if(jedis==null){
146                 broken = true;
147                 return null;
148             }
149             return jedis.lpop(list);
150         } catch (Exception e) {
151             broken = true;
152         }finally{
153             returnJedis(jedis, broken);
154         }
155         return null;
156     }
157     
158     /**
159      * 从右边出列表
160      */
161     public static String rpop(String list){
162         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
163         ShardedJedis jedis = null;
164         try {
165             jedis = getJedis();//获取jedis实例
166             if(jedis==null){
167                 broken = true;
168                 return null;
169             }
170             return jedis.rpop(list);
171         } catch (Exception e) {
172             broken = true;
173         }finally{
174             returnJedis(jedis, broken);
175         }
176         return null;
177     }
178     
179     /**
180      * 返回list中index位置的元素
181      */
182     public static String lGetIndex(String list, long index){
183         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
184         ShardedJedis jedis = null;
185         try {
186             jedis = getJedis();//获取jedis实例
187             if(jedis==null){
188                 broken = true;
189                 return null;
190             }
191             return jedis.lindex(list, index);
192         } catch (Exception e) {
193             broken = true;
194         }finally{
195             returnJedis(jedis, broken);
196         }
197         return null;
198     }
199     
200     /**
201      * 返回list指定区间[start,end]内的元素 
202      */
203     public static List<String> lrange(String list, long start, long end){
204         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
205         ShardedJedis jedis = null;
206         try {
207             jedis = getJedis();//获取jedis实例
208             if(jedis==null){
209                 broken = true;
210                 return null;
211             }
212             return jedis.lrange(list, start, end);//
213         } catch (Exception e) {
214             broken = true;
215         }finally{
216             returnJedis(jedis, broken);
217         }
218         return null;
219     }
220     
221     /**
222      * 返回list内的全部元素 
223      */
224     public static List<String> lrange(String list){
225         return lrange(list, 0, -1);
226     }
227     
228     /*** 删除缓存(删除整个list,直接用RedisStringUtil的delete就好)******/
229     /**
230      * 让list只保留指定区间[start,end]内的元素,不在指定区间内的元素都将被删除 
231      */
232     public static void ltrim(String list, long start, long end){
233         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
234         ShardedJedis jedis = null;
235         try {
236             jedis = getJedis();//获取jedis实例
237             if(jedis==null){
238                 broken = true;
239                 return;
240             }
241             jedis.ltrim(list, start, end);
242         } catch (Exception e) {
243             broken = true;
244         }finally{
245             returnJedis(jedis, broken);
246         }
247     }
248     
249     /**
250      * 删除list中所有与value相等的元素
251      * 注意:
252      * count
253      * ==0 :删除表中所有与value相等的元素
254      * >0:从表头开始向表尾搜索,移除count个与value相等的元素
255      * <0:从表尾开始向表头搜索,移除count个与value相等的元素
256      */
257     public static void lremove(String list, long count, String value){
258         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
259         ShardedJedis jedis = null;
260         try {
261             jedis = getJedis();//获取jedis实例
262             if(jedis==null){
263                 broken = true;
264                 return;
265             }
266             jedis.lrem(list, count, value);//返回删除了多少个元素
267         } catch (Exception e) {
268             broken = true;
269         }finally{
270             returnJedis(jedis, broken);
271         }
272     }
273     
274     /**
275      * 删除list中所有与value相等的元素
276      */
277     public static void lremove(String list, String value){
278         lremove(list, 0, value);
279     }
280     
281     /***************************其他*****************************/
282     /**
283      * 返回list中共有多少个元素
284      */
285     public static long llength(String list){
286         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
287         ShardedJedis jedis = null;
288         try {
289             jedis = getJedis();//获取jedis实例
290             if(jedis==null){
291                 broken = true;
292                 return 0;
293             }
294             return jedis.llen(list);
295         } catch (Exception e) {
296             broken = true;
297         }finally{
298             returnJedis(jedis, broken);
299         }
300         return 0;
301     }
302     
303     public static void main(String[] args) {
304         lpush("adminList", "jigang");
305         lpush("adminList", "nana");//头部
306         System.out.println(llength("adminList"));
307         System.out.println(lrange("adminList"));
308         //lpop("adminList");
309         //System.out.println(llength("adminList"));
310         //ltrim("adminList", 0, 1);
311         //System.out.println(lrange("adminList"));
312         //System.out.println(lpop("adminList"));//左边进左边出,栈(后进先出)
313         //System.out.println(rpop("adminList"));//左边进右边出,队列(先进先出)
314         System.out.println(lGetIndex("adminList",1));
315         
316     }
317 }
View Code

注意:

  • 元素在list中的存放顺序为:插入list的顺序(从左边插入在头部,从右边插入在尾部
  • 允许存放重复元素
  • 可用作模拟队列(queue)、堆栈(stack),支持双向操作(L--首部或者R--尾部)
  • index从0开始 -1表示结尾  -2表示倒数第二个
  • API中的 start end参数 都是包前也包后
  • 左边入队,相当于在队头插入元素,则之后的元素都要后移一位;而右边入队的话元素直接插在队尾,之前的元素的索引不变推荐使用右边入队,即队尾入队)
  • 没有从list中获取指定value的运算(这也是set/sorted set所没有的)
  • 没有直接的指定缓存过期的API(这也是set/sorted set/hash所没有的),但是可以按例如如下的方式指定缓存过期时间
     1     /**
     2      * 从左边(首部)加入列表
     3      * 并指定列表缓存过期时间
     4      */
     5     public static void lpush(String list, int expire, String... values){
     6         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
     7         ShardedJedis jedis = null;
     8         try {
     9             jedis = getJedis();//获取jedis实例
    10             if(jedis==null){
    11                 broken = true;
    12                 return;
    13             }
    14             /*
    15              * lpush(String key, String... strings);
    16              * 返回push之后的list中包含的元素个数
    17              */
    18             jedis.lpush(list, values);
    19             jedis.expire(list, expire);//为该list设置缓存过期时间
    20         } catch (Exception e) {
    21             broken = true;
    22         }finally{
    23             returnJedis(jedis, broken);
    24         }
    25     }
    View Code
  • 删除整个list可以直接使用jedis.del(list)(set/sorted set/hash同理)

 

1.2、RedisSetUtil(无序集合工具类)

  1 package com.xxx.cache.redis;
  2 
  3 import java.util.Set;
  4 
  5 import redis.clients.jedis.ShardedJedis;
  6 
  7 /**
  8  * set缓存操作类
  9  * 1、无序集合,最后的顺序不一定是插入顺序
 10  * 2、元素不能重复
 11  * 3、对于set而言,Jedis有交集、差集、并集运算,可是ShardJedis没有
 12  * 4、没有从set中获取指定value的运算
 13  */
 14 public class RedisSetUtil extends RedisBaseUtil {
 15     /***************************添加缓存*****************************/
 16     /**
 17      * 添加缓存
 18      * @param set    缓存将要添加到的set集合
 19      * @param values 添加的缓存元素
 20      */
 21     public static void sadd(String set, String... values){
 22         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 23         ShardedJedis jedis = null;
 24         try {
 25             jedis = getJedis();//获取jedis实例
 26             if(jedis==null){
 27                 broken = true;
 28                 return;
 29             }
 30             /*
 31              * 对比:
 32              * lpush(String key, String... strings);
 33              * 返回push之后的list中包含的元素个数
 34              * 
 35              * sadd(String key, String... members)
 36              * 1:添加元素成功
 37              * 0:set中已经有要添加的元素了
 38              */
 39             jedis.sadd(set, values);
 40         } catch (Exception e) {
 41             broken = true;
 42         }finally{
 43             returnJedis(jedis, broken);
 44         }
 45     }
 46     
 47     /***************************获取缓存*****************************/
 48     /**
 49      * 获取set集合中的所有缓存
 50      * @param set
 51      */
 52     public static Set<String> smembers(String set){
 53         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 54         ShardedJedis jedis = null;
 55         try {
 56             jedis = getJedis();//获取jedis实例
 57             if(jedis==null){
 58                 broken = true;
 59                 return null;
 60             }
 61             return jedis.smembers(set);
 62         } catch (Exception e) {
 63             broken = true;
 64         }finally{
 65             returnJedis(jedis, broken);
 66         }
 67         return null;
 68     }
 69     
 70     /***************************删除缓存*****************************/
 71     /**
 72      * 删除缓存
 73      * @param set
 74      * @param values
 75      */
 76     public static void sremove(String set, String... values){
 77         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 78         ShardedJedis jedis = null;
 79         try {
 80             jedis = getJedis();//获取jedis实例
 81             if(jedis==null){
 82                 broken = true;
 83                 return;
 84             }
 85             jedis.srem(set, values);
 86         } catch (Exception e) {
 87             broken = true;
 88         }finally{
 89             returnJedis(jedis, broken);
 90         }
 91     }
 92     
 93     /***************************其他*****************************/
 94     /**
 95      * set集合是否包含value
 96      * @param set
 97      */
 98     public static boolean sismembers(String set, String value){
 99         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
100         ShardedJedis jedis = null;
101         try {
102             jedis = getJedis();//获取jedis实例
103             if(jedis==null){
104                 broken = true;
105                 return false;
106             }
107             return jedis.sismember(set, value);
108         } catch (Exception e) {
109             broken = true;
110         }finally{
111             returnJedis(jedis, broken);
112         }
113         return false;
114     }
115     
116     /**
117      * 返回set集合的元素个数
118      * @param set
119      */
120     public static long ssize(String set){
121         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
122         ShardedJedis jedis = null;
123         try {
124             jedis = getJedis();//获取jedis实例
125             if(jedis==null){
126                 broken = true;
127                 return 0;
128             }
129             return jedis.scard(set);
130         } catch (Exception e) {
131             broken = true;
132         }finally{
133             returnJedis(jedis, broken);
134         }
135         return 0;
136     }
137     
138     /**
139      * 测试
140      */
141     public static void main(String[] args) {
142         sadd("adminset", "nana","jigang");
143         sadd("adminset", "nana2");
144         System.out.println(smembers("adminset"));
145         System.out.println(ssize("adminset"));
146         System.out.println(sismembers("adminset", "jigang"));
147         sremove("adminset", "jigang");
148         System.out.println(sismembers("adminset", "jigang"));
149     }
150     
151 }
View Code

注意:

  • 元素在set中的存放顺序为:与插入set的先后书顺序无关(即无序)
  • 不允许存放重复元素
  • 对于set而言,Jedis有交集、差集、并集运算,可是ShardJedis没有

 

1.3、RedisSortedSet(有序集合工具类)

  1 package com.xxx.cache.redis;
  2 
  3 import java.util.Map;
  4 import java.util.Set;
  5 
  6 import redis.clients.jedis.ShardedJedis;
  7 import redis.clients.jedis.Tuple;
  8 
  9 /**
 10  * sorted set缓存操作类 
 11  * 1、有序集合,最后的顺序是按照score从小到大的顺序排列
 12  * 2、元素不能重复
 13  * 3、没有从set中获取指定value的运算
 14  */
 15 public class RedisSortedSetUtil extends RedisBaseUtil {
 16     /***************************添加缓存*****************************/
 17     /**
 18      * 添加缓存(一个)
 19      * @param sortedSet 添加入的集合
 20      * @param score        权重
 21      * @param value        值
 22      */
 23     public static void zadd(String sortedSet,double score, String value){
 24         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 25         ShardedJedis jedis = null;
 26         try {
 27             jedis = getJedis();//获取jedis实例
 28             if(jedis==null){
 29                 broken = true;
 30                 return;
 31             }
 32             jedis.zadd(sortedSet, score, value);
 33         } catch (Exception e) {
 34             broken = true;
 35         }finally{
 36             returnJedis(jedis, broken);
 37         }
 38     }
 39     
 40     /**
 41      * 添加缓存(一次可添加多个)
 42      * @param sortedSet        添加入的集合
 43      * @param value2score    加入集合的元素集
 44      */
 45     public static void zadd(String sortedSet,Map<String, Double> value2score){
 46         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 47         ShardedJedis jedis = null;
 48         try {
 49             jedis = getJedis();//获取jedis实例
 50             if(jedis==null){
 51                 broken = true;
 52                 return;
 53             }
 54             jedis.zadd(sortedSet, value2score);
 55         } catch (Exception e) {
 56             broken = true;
 57         }finally{
 58             returnJedis(jedis, broken);
 59         }
 60     }
 61     
 62     /***************************获取缓存*****************************/
 63     /**
 64      * 返回sortedSet内[start,end]索引的元素set
 65      * 1、在sortedSet中,元素是按照score从小到大排列的,
 66      *         此方法从前向后获取元素(即按元素的score从小到大排列)
 67      * @param sortedSet
 68      * @param start
 69      * @param end
 70      */
 71     public static Set<String> zrange(String sortedSet, long start, long end){
 72         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 73         ShardedJedis jedis = null;
 74         try {
 75             jedis = getJedis();//获取jedis实例
 76             if(jedis==null){
 77                 broken = true;
 78                 return null;
 79             }
 80             return jedis.zrange(sortedSet, start, end);
 81         } catch (Exception e) {
 82             broken = true;
 83         }finally{
 84             returnJedis(jedis, broken);
 85         }
 86         return null;
 87     }
 88     
 89     /**
 90      * 返回sortedSet内所有元素,元素按照score从小到大排列
 91      */
 92     public static Set<String> zrange(String sortedSet){
 93         return zrange(sortedSet, 0, -1);
 94     }
 95     
 96     /**
 97      * 返回sortedSet集合[start, end]中的元素
 98      * 1、此方法相当于从后向前取元素,即元素从大到小排列
 99      * 或者相当于将sortedSet从大到小排列,然后从前向后去元素
100      * @param sortedSet
101      * @param start
102      * @param end
103      * @return
104      */
105     public static Set<String> zrevrange(String sortedSet, long start, long end){
106         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
107         ShardedJedis jedis = null;
108         try {
109             jedis = getJedis();//获取jedis实例
110             if(jedis==null){
111                 broken = true;
112                 return null;
113             }
114             return jedis.zrevrange(sortedSet, start, end);
115         } catch (Exception e) {
116             broken = true;
117         }finally{
118             returnJedis(jedis, broken);
119         }
120         return null;
121     }
122     
123     /**
124      * 返回sortedSet内所有元素,元素按照score从大到小排列
125      */
126     public static Set<String> zrevrange(String sortedSet){
127         return zrevrange(sortedSet, 0, -1);
128     }
129     
130     /**
131      * 获取sortedSet内[minScore, maxScore]的元素
132      * @param sortedSet
133      * @param minScore
134      * @param maxScore
135      * @return
136      */
137     public static Set<String> zrangeByScore(String sortedSet, double minScore, double maxScore){
138         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
139         ShardedJedis jedis = null;
140         try {
141             jedis = getJedis();//获取jedis实例
142             if(jedis==null){
143                 broken = true;
144                 return null;
145             }
146             return jedis.zrangeByScore(sortedSet, minScore, maxScore);
147         } catch (Exception e) {
148             broken = true;
149         }finally{
150             returnJedis(jedis, broken);
151         }
152         return null;
153     }
154     
155     /**
156      * 获取Set<Tuple>集合,其中Tuple是value与score的结构体
157      * @param sortedSet
158      * @param minScore
159      * @param maxScore
160      * @return
161      */
162     public static Set<Tuple> zrevrangeByScoreWithScores(String sortedSet, double minScore, double maxScore){
163         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
164         ShardedJedis jedis = null;
165         try {
166             jedis = getJedis();//获取jedis实例
167             if(jedis==null){
168                 broken = true;
169                 return null;
170             }
171             return jedis.zrevrangeByScoreWithScores(sortedSet, maxScore, minScore);
172         } catch (Exception e) {
173             broken = true;
174         }finally{
175             returnJedis(jedis, broken);
176         }
177         return null;
178     }
179     
180     /***************************删除缓存*****************************/
181     /**
182      * 删除多个缓存
183      * @param sortedSet
184      * @param values
185      */
186     public static void zremove(String sortedSet, String... values){
187         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
188         ShardedJedis jedis = null;
189         try {
190             jedis = getJedis();//获取jedis实例
191             if(jedis==null){
192                 broken = true;
193                 return;
194             }
195             jedis.zrem(sortedSet, values);
196         } catch (Exception e) {
197             broken = true;
198         }finally{
199             returnJedis(jedis, broken);
200         }
201     }
202     
203     /**
204      * 删除指定范围(按照索引,包前包后)的缓存
205      * @param sortedSet
206      * @param start
207      * @param end
208      */
209     public static void zremrangeByRank(String sortedSet, long start, long end){
210         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
211         ShardedJedis jedis = null;
212         try {
213             jedis = getJedis();//获取jedis实例
214             if(jedis==null){
215                 broken = true;
216                 return;
217             }
218             jedis.zremrangeByRank(sortedSet, start, end);
219         } catch (Exception e) {
220             broken = true;
221         }finally{
222             returnJedis(jedis, broken);
223         }
224     }
225     
226     /**
227      * 删除指定范围(按照分数,包前包后)的缓存
228      * @param sortedSet
229      * @param minScore
230      * @param maxScore
231      */
232     public static void zremrangeByScore(String sortedSet, double minScore, double maxScore){
233         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
234         ShardedJedis jedis = null;
235         try {
236             jedis = getJedis();//获取jedis实例
237             if(jedis==null){
238                 broken = true;
239                 return;
240             }
241             jedis.zremrangeByScore(sortedSet, minScore, maxScore);
242         } catch (Exception e) {
243             broken = true;
244         }finally{
245             returnJedis(jedis, broken);
246         }
247     }
248     
249     /***************************其他*****************************/
250     /**
251      * 获取集合sortedSet的长度
252      * @param sortedSet
253      * @return
254      */
255     public static long zlength(String sortedSet){
256         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
257         ShardedJedis jedis = null;
258         try {
259             jedis = getJedis();//获取jedis实例
260             if(jedis==null){
261                 broken = true;
262                 return 0;
263             }
264             return jedis.zcard(sortedSet);
265         } catch (Exception e) {
266             broken = true;
267         }finally{
268             returnJedis(jedis, broken);
269         }
270         return 0;
271     }
272     
273     /**
274      * 获取sortedSet中的value的权重score
275      * @param sortedSet
276      * @param value
277      * @return
278      */
279     public static double zscore(String sortedSet, String value){
280         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
281         ShardedJedis jedis = null;
282         try {
283             jedis = getJedis();//获取jedis实例
284             if(jedis==null){
285                 broken = true;
286                 return 0;
287             }
288             return jedis.zscore(sortedSet, value);
289         } catch (Exception e) {
290             broken = true;
291         }finally{
292             returnJedis(jedis, broken);
293         }
294         return 0;
295     }
296     
297     /**
298      * 为sortedSet中的value的权重加上增量score
299      * @param sortedSet
300      * @param score
301      * @param value
302      */
303     public static void zincrby(String sortedSet,double score, String value){
304         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
305         ShardedJedis jedis = null;
306         try {
307             jedis = getJedis();//获取jedis实例
308             if(jedis==null){
309                 broken = true;
310                 return;
311             }
312             jedis.zincrby(sortedSet, score, value);
313         } catch (Exception e) {
314             broken = true;
315         }finally{
316             returnJedis(jedis, broken);
317         }
318     }
319 
320     /**
321      * 测试
322      */
323     public static void main(String[] args) {
324         zadd("aaset", 1, "aa");
325         zadd("aaset", 4, "bb");
326         zadd("aaset", 0, "cc");
327         
328         System.out.println(zrange("aaset", 0, -1));//[cc, aa, bb]
329         System.out.println(zrange("aaset", 0, 1));//[cc, aa]
330         System.out.println(zrevrange("aaset", 0, -1));//[bb, aa, cc]
331         System.out.println(zrevrange("aaset", 0, 1));//[bb, aa]
332         System.out.println(zrangeByScore("aaset", 0, 2));//[cc, aa]
333         Set<Tuple> s = zrevrangeByScoreWithScores("aaset", 0, 2);
334         for(Tuple t : s){
335             System.out.println(t.getElement()+"-->"+t.getScore());//aa-->1.0  cc-->0.0
336         }
337         
338         System.out.println(zlength("aaset"));//3
339         System.out.println(zscore("aaset","bb"));//4.0
340         zincrby("aaset",10,"bb");
341         System.out.println(zscore("aaset","bb"));//14.0
342         zremove("aaset", "cc");
343         System.out.println(zrange("aaset"));//[aa, bb]
344         zremrangeByScore("aaset", 10, 20);
345         System.out.println(zrange("aaset"));//[aa]
346     }
347 
348 }
View Code

注意:

  • 元素在set中的存放顺序为:根据score(权重)从小到大排列
  • 不允许存放重复元素

 

1.4、RedisHashUtil(hash工具类)

  1 package com.xxx.cache.redis;
  2 
  3 import java.util.HashMap;
  4 import java.util.List;
  5 import java.util.Map;
  6 import java.util.Set;
  7 
  8 import redis.clients.jedis.ShardedJedis;
  9 
 10 /**
 11  * hash缓存操作类
 12  */
 13 public class RedisHashUtil extends RedisBaseUtil {
 14     /***************************添加缓存*****************************/
 15     /**
 16      * 添加单个缓存key-value到map中
 17      */
 18     public static void hset(String map, String key, String value){
 19         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 20         ShardedJedis jedis = null;
 21         try {
 22             jedis = getJedis();//获取jedis实例
 23             if(jedis==null){
 24                 broken = true;
 25                 return;
 26             }
 27             jedis.hset(map, key, value);
 28         } catch (Exception e) {
 29             broken = true;
 30         }finally{
 31             returnJedis(jedis, broken);
 32         }
 33     }
 34     
 35     /**
 36      * 添加单个缓存key-value到map中
 37      * 若已经存在于指定key相同的key,那么就不操作
 38      */
 39     public static void hsetnx(String map, String key, String value){
 40         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 41         ShardedJedis jedis = null;
 42         try {
 43             jedis = getJedis();//获取jedis实例
 44             if(jedis==null){
 45                 broken = true;
 46                 return;
 47             }
 48             jedis.hsetnx(map, key, value);
 49         } catch (Exception e) {
 50             broken = true;
 51         }finally{
 52             returnJedis(jedis, broken);
 53         }
 54     }
 55     
 56     /**
 57      * 在map中添加key2value的map,即一次性添加多条缓存
 58      * @param map
 59      * @param key2value
 60      */
 61     public static void hmset(String map, Map<String, String> key2value){
 62         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 63         ShardedJedis jedis = null;
 64         try {
 65             jedis = getJedis();//获取jedis实例
 66             if(jedis==null){
 67                 broken = true;
 68                 return;
 69             }
 70             jedis.hmset(map, key2value);
 71         } catch (Exception e) {
 72             broken = true;
 73         }finally{
 74             returnJedis(jedis, broken);
 75         }
 76     }
 77     
 78     /***************************获取缓存*****************************/
 79     /**
 80      * 获取map中key的集合
 81      * @param set
 82      */
 83     public static Set<String> hkeys(String map){
 84         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
 85         ShardedJedis jedis = null;
 86         try {
 87             jedis = getJedis();//获取jedis实例
 88             if(jedis==null){
 89                 broken = true;
 90                 return null;
 91             }
 92             return jedis.hkeys(map);
 93         } catch (Exception e) {
 94             broken = true;
 95         }finally{
 96             returnJedis(jedis, broken);
 97         }
 98         return null;
 99     }
100     
101     /**
102      * 获取map中的所有key的value
103      */
104     public static List<String> hvals(String map){
105         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
106         ShardedJedis jedis = null;
107         try {
108             jedis = getJedis();//获取jedis实例
109             if(jedis==null){
110                 broken = true;
111                 return null;
112             }
113             return jedis.hvals(map);
114         } catch (Exception e) {
115             broken = true;
116         }finally{
117             returnJedis(jedis, broken);
118         }
119         return null;
120     }
121     
122     /**
123      * 从map中获取多个key的value,并放在List集合中
124      */
125     public static List<String> hmget(String map, String... keys){
126         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
127         ShardedJedis jedis = null;
128         try {
129             jedis = getJedis();//获取jedis实例
130             if(jedis==null){
131                 broken = true;
132                 return null;
133             }
134             return jedis.hmget(map, keys);
135         } catch (Exception e) {
136             broken = true;
137         }finally{
138             returnJedis(jedis, broken);
139         }
140         return null;
141     }
142     
143     /**
144      * 从map中获取全部的缓存key-value对
145      */
146     public static Map<String, String> hgetAll(String map){
147         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
148         ShardedJedis jedis = null;
149         try {
150             jedis = getJedis();//获取jedis实例
151             if(jedis==null){
152                 broken = true;
153                 return null;
154             }
155             return jedis.hgetAll(map);
156         } catch (Exception e) {
157             broken = true;
158         }finally{
159             returnJedis(jedis, broken);
160         }
161         return null;
162     }
163     
164     /**
165      * 从map中获取相应key的缓存value
166      */
167     public static String hget(String map, String key){
168         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
169         ShardedJedis jedis = null;
170         try {
171             jedis = getJedis();//获取jedis实例
172             if(jedis==null){
173                 broken = true;
174                 return null;
175             }
176             return jedis.hget(map, key);
177         } catch (Exception e) {
178             broken = true;
179         }finally{
180             returnJedis(jedis, broken);
181         }
182         return null;
183     }
184     
185     /***************************删除缓存*****************************/
186     /**
187      * 从map中删除多个缓存
188      */
189     public static void hdel(String map, String... keys){
190         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
191         ShardedJedis jedis = null;
192         try {
193             jedis = getJedis();//获取jedis实例
194             if(jedis==null){
195                 broken = true;
196                 return;
197             }
198             jedis.hdel(map, keys);
199         } catch (Exception e) {
200             broken = true;
201         }finally{
202             returnJedis(jedis, broken);
203         }
204     }
205     
206     /***************************其他*****************************/
207     /**
208      * 获取map中的key-value数
209      */
210     public static long hlen(String map){
211         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
212         ShardedJedis jedis = null;
213         try {
214             jedis = getJedis();//获取jedis实例
215             if(jedis==null){
216                 broken = true;
217                 return 0;
218             }
219             return jedis.hlen(map);
220         } catch (Exception e) {
221             broken = true;
222         }finally{
223             returnJedis(jedis, broken);
224         }
225         return 0;
226     }
227     
228     /**
229      * map中是否存在键为key的缓存
230      */
231     public static boolean hexists(String map, String key){
232         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
233         ShardedJedis jedis = null;
234         try {
235             jedis = getJedis();//获取jedis实例
236             if(jedis==null){
237                 broken = true;
238                 return false;
239             }
240             return jedis.hexists(map, key);
241         } catch (Exception e) {
242             broken = true;
243         }finally{
244             returnJedis(jedis, broken);
245         }
246         return false;
247     }
248     
249     /**
250      * 测试
251      */
252     public static void main(String[] args) {
253         hset("aamap", "aa1", "aa11");
254         Map<String,String> maps = new HashMap<String, String>();
255         maps.put("aa2", "aa22");
256         maps.put("aa3", "aa33");
257         hmset("aamap", maps);
258         
259         System.out.println(hkeys("aamap"));//[aa3, aa2, aa1]
260         System.out.println(hvals("aamap"));//[aa33, aa22, aa11]
261         System.out.println(hgetAll("aamap"));//{aa3=aa33, aa2=aa22, aa1=aa11}
262         System.out.println(hget("aamap","aa2"));//aa22
263         System.out.println(hmget("aamap","aa2","aa1"));//[aa22, aa11]
264         
265         System.out.println(hlen("aamap"));//3
266         System.out.println(hexists("aamap","aa3"));//true
267         System.out.println(hexists("aamap","aa0"));//false
268         
269         hdel("aamap","aa0");
270         hdel("aamap","aa1");
271         System.out.println(hgetAll("aamap"));//{aa3=aa33, aa2=aa22}
272         
273     }
274 }
View Code

注意:

  • 有根据key获取缓存value的方法

 

1.5、RedisCacheConstant(创建一些redis使用的自定义的map/set/list/soretd set名)

1 package com.xxx.cache.util;
2 
3 /**
4  * 创建一些redis使用的自定义的map/set/list/soretd set名
5  */
6 public enum RedisCacheConstant {
7     USER_MANAGEMENT_MAP,    //人员管理业务类缓存map
8     HOTEL_MANAGEMENT_MAP;    //酒店管理业务类缓存map
9 }
View Code

注意:

  • 这一块儿与业务有关
  • 在我们的API的设计过程中,可以直接将自己封装的方法中的list/set/sorted set/map参数的类型有String改为RedisCacheConstant,而在方法内部你调用ShardJedis的API的时候,使用String.valueOf(RedisCacheConstant)这样的方式,这样就会减少在实际开发中的代码量。

 

2、ssmm0-data

AdminService:

 1     /*********************redis hash********************/
 2     /*
 3      * 此处用set、list、sorted set都不太好,因为三者都不具备根据key查找值的能力,
 4      * 以set为例,你缓存的时候,只能缓存一个id进去,最后查询缓存,查到缓存中有ID之后,还需要再根据此ID查询数据库,才能返回具体的admin,还不如直接根据ID去数据库查询
 5      * 
 6      * set的一个典型应用场景:
 7      * 当有用户注册或者用户信息修改或用户被删除之后,我们将其ID放入缓存,
 8      * 之后可能会启动一个定时任务,定时扫描该set中是否有ID存在,如果有,说明有用户信息发生变化,
 9      * 然后再进行一些操作,操作之后将set清空。之后继续循环上述的方式
10      * 
11      * 这里有个问题?set的操作是线程安全的吗?
12      */
13     public Admin findAdminByIdFromRedisHash(int id) {
14         //从缓存中获取数据:注意这里可以直接将RedisHashUtil中的hget方法的map改为RedisCacheConstant类型,下边同理,其他set、list、sorted set也同理
15         String adminStr = RedisHashUtil.hget(String.valueOf(RedisCacheConstant.USER_MANAGEMENT_MAP), String.valueOf(id));
16         //若缓存中有,直接返回
17         if(StringUtils.isNoneBlank(adminStr)){
18             return Admin.parseJsonToAdmin(adminStr);
19         }
20         //若缓存中没有,从数据库查询
21         Admin admin = adminDao.getUserById(id);
22         //若查询出的数据不为null
23         if(admin!=null){
24             //将数据存入缓存
25             RedisHashUtil.hset(String.valueOf(RedisCacheConstant.USER_MANAGEMENT_MAP), String.valueOf(id), admin.toJson());
26         }
27         //返回从数据库查询的admin(当然也可能数据库中也没有,就是null)
28         return admin;
29     }
View Code

说明:在AdminService类中只添加了如上方法。

注意:

  • String、hash具有按key查找value的功能
  • list、set、sorted set没有按key查找的功能

适用场景:

  • 需要按key查找value的,用hash和String
  • set类的两种典型应用场景:(归结为一句话:存储特殊的key,之后可能还需要根据这些key进行数据库的查询
    • 当有用户注册或者用户信息修改或用户被删除之后,我们将其ID放入缓存,之后可能会启动一个定时任务,定时扫描该set中是否有ID存在,如果有,说明有用户信息发生变化,然后再进行一些操作,操作之后将set清空。之后继续循环上述的方式
    • 存储一个网站的活跃的用户ID,之后我们可以确定set中存在的所有ID都是活跃用户,之后可以按照他们的ID进行数据库的查询;如果用MySQL去做这个事儿,可能需要扫描全表,然后再进行一些操作

 

3、ssmm0-userManagement

AdminController:

1     /**
2      * 根据id查找Admin
3      */
4     @ResponseBody
5     @RequestMapping("/findAdminByIdFromRedisHash")
6     public Admin findAdminByIdFromRedisHash(@RequestParam(value="id") int id){
7         
8         return adminService.findAdminByIdFromRedisHash(id);
9     }
View Code

说明:AdminController中只添加了如上方法。

 

4、测试

测试方法同上一章。

 

总结:

  • list
    • 元素在list中的存放顺序为:插入list的顺序(从左边插入在头部,从右边插入在尾部)
    • 允许存放重复元素
    • 可用作模拟队列(queue)、堆栈(stack),支持双向操作(L--首部或者R--尾部)
    • 左边入队,相当于在队头插入元素,则之后的元素都要后移一位;而右边入队的话元素直接插在队尾,之前的元素的索引不变(推荐使用右边入队,即队尾入队)
  • set
    • 元素在set中的存放顺序为:与插入set的先后书顺序无关(即无序)
    • 不允许存放重复元素
    • 对于set而言,Jedis有交集、差集、并集运算,可是ShardJedis没有
  • soretd set
    • 元素在set中的存放顺序为:根据score(权重)从小到大排列
    • 不允许存放重复元素

相同点:

  • index
    • 从0开始 -1表示结尾  -2表示倒数第二个
  • API中的 start end参数
    • 都是包前也包后的
  • 按key查找功能
    • list、set、sorted set没有按key查找的功能
    • String、hash具有按key查找value的功能
  • 直接的指定缓存过期的API
    • String有
    • list、set、sorted set、hash没有,但是可以按例如如下的方式指定缓存过期时间
       1     /**
       2      * 从左边(首部)加入列表
       3      * 并指定列表缓存过期时间
       4      */
       5     public static void lpush(String list, int expire, String... values){
       6         boolean broken = false;//标记:该操作是否被异常打断而没有正常结束
       7         ShardedJedis jedis = null;
       8         try {
       9             jedis = getJedis();//获取jedis实例
      10             if(jedis==null){
      11                 broken = true;
      12                 return;
      13             }
      14             /*
      15              * lpush(String key, String... strings);
      16              * 返回push之后的list中包含的元素个数
      17              */
      18             jedis.lpush(list, values);
      19             jedis.expire(list, expire);//为该list设置缓存过期时间
      20         } catch (Exception e) {
      21             broken = true;
      22         }finally{
      23             returnJedis(jedis, broken);
      24         }
      25     }
      View Code
  • 删除整个元素
    • jedis.del(list):可用于五种结构

 

疑问:关于jedis、xmemcached的线程安全问题,是如何解决的?

posted on 2016-01-29 10:55  赵计刚  阅读(2066)  评论(0编辑  收藏  举报