1. 程式人生 > 實用技巧 >spring boot整合redis快取

spring boot整合redis快取

上一個文字講了redis的安裝與執行,本次就不再贅述,本文講解使用spring boot專案整合redis

第一步:先看下專案目錄構成,紅框的部分是redis的類與配置內容,如下:

1、增加redis依賴項,在pom檔案中增加

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

2、建立redis的配置類RedisConfig

  1 package com.yl.demo.conf;
  2 
  3 import com.fasterxml.jackson.annotation.JsonAutoDetect;
  4 import com.fasterxml.jackson.annotation.PropertyAccessor;
  5 import com.fasterxml.jackson.databind.ObjectMapper;
  6 import org.springframework.cache.annotation.CachingConfigurerSupport;
7 import org.springframework.cache.annotation.EnableCaching; 8 import org.springframework.context.annotation.Bean; 9 import org.springframework.context.annotation.Configuration; 10 import org.springframework.data.redis.connection.RedisConnectionFactory; 11 import org.springframework.data.redis.core.*;
12 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 13 import org.springframework.data.redis.serializer.StringRedisSerializer; 14 15 /** 16 * redis配置類 17 * @program: springbootdemo 18 * @Date: 2020/7/11 19 * @Author: yangl 20 * @Description: 21 */ 22 @Configuration 23 @EnableCaching //開啟註解 24 public class RedisConfig extends CachingConfigurerSupport { 25 26 /** 27 * retemplate相關配置 28 * @param factory 29 * @return 30 */ 31 @Bean 32 public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { 33 34 RedisTemplate<String, Object> template = new RedisTemplate<>(); 35 // 配置連線工廠 36 template.setConnectionFactory(factory); 37 38 //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(預設使用JDK的序列化方式) 39 Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class); 40 41 ObjectMapper om = new ObjectMapper(); 42 // 指定要序列化的域,field,get和set,以及修飾符範圍,ANY是都有包括private和public 43 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 44 // 指定序列化輸入的型別,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常 45 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 46 jacksonSeial.setObjectMapper(om); 47 48 // 值採用json序列化 49 template.setValueSerializer(jacksonSeial); 50 //使用StringRedisSerializer來序列化和反序列化redis的key值 51 template.setKeySerializer(new StringRedisSerializer()); 52 53 // 設定hash key 和value序列化模式 54 template.setHashKeySerializer(new StringRedisSerializer()); 55 template.setHashValueSerializer(jacksonSeial); 56 template.afterPropertiesSet(); 57 58 return template; 59 } 60 61 /** 62 * 對hash型別的資料操作 63 * 64 * @param redisTemplate 65 * @return 66 */ 67 @Bean 68 public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { 69 return redisTemplate.opsForHash(); 70 } 71 72 /** 73 * 對redis字串型別資料操作 74 * 75 * @param redisTemplate 76 * @return 77 */ 78 @Bean 79 public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) { 80 return redisTemplate.opsForValue(); 81 } 82 83 /** 84 * 對連結串列型別的資料操作 85 * 86 * @param redisTemplate 87 * @return 88 */ 89 @Bean 90 public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { 91 return redisTemplate.opsForList(); 92 } 93 94 /** 95 * 對無序集合型別的資料操作 96 * 97 * @param redisTemplate 98 * @return 99 */ 100 @Bean 101 public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { 102 return redisTemplate.opsForSet(); 103 } 104 105 /** 106 * 對有序集合型別的資料操作 107 * 108 * @param redisTemplate 109 * @return 110 */ 111 @Bean 112 public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) { 113 return redisTemplate.opsForZSet(); 114 } 115 116 }

3、建立redis工具類RedisUtil

  1 package com.yl.demo.utils;
  2 
  3 import org.springframework.beans.factory.annotation.Autowired;
  4 import org.springframework.data.redis.core.RedisTemplate;
  5 import org.springframework.stereotype.Component;
  6 import org.springframework.util.CollectionUtils;
  7 
  8 import java.util.List;
  9 import java.util.Map;
 10 import java.util.Set;
 11 import java.util.concurrent.TimeUnit;
 12 
 13 /**
 14  * redisTemplate封裝
 15  * @Date 2020-07-11
 16  *  @author yanglei
 17  */
 18 @Component
 19 public class RedisUtil {
 20 
 21     @Autowired
 22     private RedisTemplate<String, Object> redisTemplate;
 23 
 24     public RedisUtil(RedisTemplate<String, Object> redisTemplate) {
 25         this.redisTemplate = redisTemplate;
 26     }
 27 
 28     /**
 29      * 指定快取失效時間
 30      * @param key 鍵
 31      * @param time 時間(秒)
 32      * @return
 33      */
 34     public boolean expire(String key,long time){
 35         try {
 36             if(time>0){
 37                 redisTemplate.expire(key, time, TimeUnit.SECONDS);
 38             }
 39             return true;
 40         } catch (Exception e) {
 41             e.printStackTrace();
 42             return false;
 43         }
 44     }
 45 
 46     /**
 47      * 根據key 獲取過期時間
 48      * @param key 鍵 不能為null
 49      * @return 時間(秒) 返回0代表為永久有效
 50      */
 51     public long getExpire(String key){
 52         return redisTemplate.getExpire(key,TimeUnit.SECONDS);
 53     }
 54 
 55     /**
 56      * 判斷key是否存在
 57      * @param key 鍵
 58      * @return true 存在 false不存在
 59      */
 60     public boolean hasKey(String key){
 61         try {
 62             return redisTemplate.hasKey(key);
 63         } catch (Exception e) {
 64             e.printStackTrace();
 65             return false;
 66         }
 67     }
 68 
 69     /**
 70      * 刪除快取
 71      * @param key 可以傳一個值 或多個
 72      */
 73     @SuppressWarnings("unchecked")
 74     public void del(String ... key){
 75         if(key!=null&&key.length>0){
 76             if(key.length==1){
 77                 redisTemplate.delete(key[0]);
 78             }else{
 79                 redisTemplate.delete(CollectionUtils.arrayToList(key));
 80             }
 81         }
 82     }
 83 
 84     //============================String=============================
 85     /**
 86      * 普通快取獲取
 87      * @param key 鍵
 88      * @return 89      */
 90     public Object get(String key){
 91         return key==null?null:redisTemplate.opsForValue().get(key);
 92     }
 93 
 94     /**
 95      * 普通快取放入
 96      * @param key 鍵
 97      * @param value 值
 98      * @return true成功 false失敗
 99      */
100     public boolean set(String key,Object value) {
101         try {
102             redisTemplate.opsForValue().set(key, value);
103             return true;
104         } catch (Exception e) {
105             e.printStackTrace();
106             return false;
107         }
108     }
109 
110     /**
111      * 普通快取放入並設定時間
112      * @param key 鍵
113      * @param value 值
114      * @param time 時間(秒) time要大於0 如果time小於等於0 將設定無限期
115      * @return true成功 false 失敗
116      */
117     public boolean set(String key,Object value,long time){
118         try {
119             if(time>0){
120                 redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
121             }else{
122                 set(key, value);
123             }
124             return true;
125         } catch (Exception e) {
126             e.printStackTrace();
127             return false;
128         }
129     }
130 
131     /**
132      * 遞增
133      * @param key 鍵
134      * @param delta 要增加幾(大於0)
135      * @return
136      */
137     public long incr(String key, long delta){
138         if(delta<0){
139             throw new RuntimeException("遞增因子必須大於0");
140         }
141         return redisTemplate.opsForValue().increment(key, delta);
142     }
143 
144     /**
145      * 遞減
146      * @param key 鍵
147      * @param delta 要減少幾(小於0)
148      * @return
149      */
150     public long decr(String key, long delta){
151         if(delta<0){
152             throw new RuntimeException("遞減因子必須大於0");
153         }
154         return redisTemplate.opsForValue().increment(key, -delta);
155     }
156 
157     //================================Map=================================
158     /**
159      * HashGet
160      * @param key 鍵 不能為null
161      * @param item 項 不能為null
162      * @return163      */
164     public Object hget(String key,String item){
165         return redisTemplate.opsForHash().get(key, item);
166     }
167 
168     /**
169      * 獲取hashKey對應的所有鍵值
170      * @param key 鍵
171      * @return 對應的多個鍵值
172      */
173     public Map<Object,Object> hmget(String key){
174         return redisTemplate.opsForHash().entries(key);
175     }
176 
177     /**
178      * HashSet
179      * @param key 鍵
180      * @param map 對應多個鍵值
181      * @return true 成功 false 失敗
182      */
183     public boolean hmset(String key, Map<String,Object> map){
184         try {
185             redisTemplate.opsForHash().putAll(key, map);
186             return true;
187         } catch (Exception e) {
188             e.printStackTrace();
189             return false;
190         }
191     }
192 
193     /**
194      * HashSet 並設定時間
195      * @param key 鍵
196      * @param map 對應多個鍵值
197      * @param time 時間(秒)
198      * @return true成功 false失敗
199      */
200     public boolean hmset(String key, Map<String,Object> map, long time){
201         try {
202             redisTemplate.opsForHash().putAll(key, map);
203             if(time>0){
204                 expire(key, time);
205             }
206             return true;
207         } catch (Exception e) {
208             e.printStackTrace();
209             return false;
210         }
211     }
212 
213     /**
214      * 向一張hash表中放入資料,如果不存在將建立
215      * @param key 鍵
216      * @param item 項
217      * @param value 值
218      * @return true 成功 false失敗
219      */
220     public boolean hset(String key,String item,Object value) {
221         try {
222             redisTemplate.opsForHash().put(key, item, value);
223             return true;
224         } catch (Exception e) {
225             e.printStackTrace();
226             return false;
227         }
228     }
229 
230     /**
231      * 向一張hash表中放入資料,如果不存在將建立
232      * @param key 鍵
233      * @param item 項
234      * @param value 值
235      * @param time 時間(秒)  注意:如果已存在的hash表有時間,這裡將會替換原有的時間
236      * @return true 成功 false失敗
237      */
238     public boolean hset(String key,String item,Object value,long time) {
239         try {
240             redisTemplate.opsForHash().put(key, item, value);
241             if(time>0){
242                 expire(key, time);
243             }
244             return true;
245         } catch (Exception e) {
246             e.printStackTrace();
247             return false;
248         }
249     }
250 
251     /**
252      * 刪除hash表中的值
253      * @param key 鍵 不能為null
254      * @param item 項 可以使多個 不能為null
255      */
256     public void hdel(String key, Object... item){
257         redisTemplate.opsForHash().delete(key,item);
258     }
259 
260     /**
261      * 判斷hash表中是否有該項的值
262      * @param key 鍵 不能為null
263      * @param item 項 不能為null
264      * @return true 存在 false不存在
265      */
266     public boolean hHasKey(String key, String item){
267         return redisTemplate.opsForHash().hasKey(key, item);
268     }
269 
270     /**
271      * hash遞增 如果不存在,就會建立一個 並把新增後的值返回
272      * @param key 鍵
273      * @param item 項
274      * @param by 要增加幾(大於0)
275      * @return
276      */
277     public double hincr(String key, String item,double by){
278         return redisTemplate.opsForHash().increment(key, item, by);
279     }
280 
281     /**
282      * hash遞減
283      * @param key 鍵
284      * @param item 項
285      * @param by 要減少記(小於0)
286      * @return
287      */
288     public double hdecr(String key, String item,double by){
289         return redisTemplate.opsForHash().increment(key, item,-by);
290     }
291 
292     //============================set=============================
293     /**
294      * 根據key獲取Set中的所有值
295      * @param key 鍵
296      * @return
297      */
298     public Set<Object> sGet(String key){
299         try {
300             return redisTemplate.opsForSet().members(key);
301         } catch (Exception e) {
302             e.printStackTrace();
303             return null;
304         }
305     }
306 
307     /**
308      * 根據value從一個set中查詢,是否存在
309      * @param key 鍵
310      * @param value 值
311      * @return true 存在 false不存在
312      */
313     public boolean sHasKey(String key,Object value){
314         try {
315             return redisTemplate.opsForSet().isMember(key, value);
316         } catch (Exception e) {
317             e.printStackTrace();
318             return false;
319         }
320     }
321 
322     /**
323      * 將資料放入set快取
324      * @param key 鍵
325      * @param values 值 可以是多個
326      * @return 成功個數
327      */
328     public long sSet(String key, Object...values) {
329         try {
330             return redisTemplate.opsForSet().add(key, values);
331         } catch (Exception e) {
332             e.printStackTrace();
333             return 0;
334         }
335     }
336 
337     /**
338      * 將set資料放入快取
339      * @param key 鍵
340      * @param time 時間(秒)
341      * @param values 值 可以是多個
342      * @return 成功個數
343      */
344     public long sSetAndTime(String key,long time,Object...values) {
345         try {
346             Long count = redisTemplate.opsForSet().add(key, values);
347             if(time>0) {
348                 expire(key, time);
349             }
350             return count;
351         } catch (Exception e) {
352             e.printStackTrace();
353             return 0;
354         }
355     }
356 
357     /**
358      * 獲取set快取的長度
359      * @param key 鍵
360      * @return
361      */
362     public long sGetSetSize(String key){
363         try {
364             return redisTemplate.opsForSet().size(key);
365         } catch (Exception e) {
366             e.printStackTrace();
367             return 0;
368         }
369     }
370 
371     /**
372      * 移除值為value的
373      * @param key 鍵
374      * @param values 值 可以是多個
375      * @return 移除的個數
376      */
377     public long setRemove(String key, Object ...values) {
378         try {
379             Long count = redisTemplate.opsForSet().remove(key, values);
380             return count;
381         } catch (Exception e) {
382             e.printStackTrace();
383             return 0;
384         }
385     }
386     //===============================list=================================
387 
388     /**
389      * 獲取list快取的內容
390      * @param key 鍵
391      * @param start 開始
392      * @param end 結束  0 到 -1代表所有值
393      * @return
394      */
395     public List<Object> lGet(String key, long start, long end){
396         try {
397             return redisTemplate.opsForList().range(key, start, end);
398         } catch (Exception e) {
399             e.printStackTrace();
400             return null;
401         }
402     }
403 
404     /**
405      * 獲取list快取的長度
406      * @param key 鍵
407      * @return
408      */
409     public long lGetListSize(String key){
410         try {
411             return redisTemplate.opsForList().size(key);
412         } catch (Exception e) {
413             e.printStackTrace();
414             return 0;
415         }
416     }
417 
418     /**
419      * 通過索引 獲取list中的值
420      * @param key 鍵
421      * @param index 索引  index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推
422      * @return
423      */
424     public Object lGetIndex(String key,long index){
425         try {
426             return redisTemplate.opsForList().index(key, index);
427         } catch (Exception e) {
428             e.printStackTrace();
429             return null;
430         }
431     }
432 
433     /**
434      * 將list放入快取
435      * @param key 鍵
436      * @param value 值
437      * @return
438      */
439     public boolean lSet(String key, Object value) {
440         try {
441             redisTemplate.opsForList().rightPush(key, value);
442             return true;
443         } catch (Exception e) {
444             e.printStackTrace();
445             return false;
446         }
447     }
448 
449     /**
450      * 將list放入快取
451      * @param key 鍵
452      * @param value 值
453      * @param time 時間(秒)
454      * @return
455      */
456     public boolean lSet(String key, Object value, long time) {
457         try {
458             redisTemplate.opsForList().rightPush(key, value);
459             if (time > 0) {
460                 expire(key, time);
461             }
462             return true;
463         } catch (Exception e) {
464             e.printStackTrace();
465             return false;
466         }
467     }
468 
469     /**
470      * 將list放入快取
471      * @param key 鍵
472      * @param value 值
473      * @return
474      */
475     public boolean lSet(String key, List<Object> value) {
476         try {
477             redisTemplate.opsForList().rightPushAll(key, value);
478             return true;
479         } catch (Exception e) {
480             e.printStackTrace();
481             return false;
482         }
483     }
484 
485     /**
486      * 將list放入快取
487      * @param key 鍵
488      * @param value 值
489      * @param time 時間(秒)
490      * @return
491      */
492     public boolean lSet(String key, List<Object> value, long time) {
493         try {
494             redisTemplate.opsForList().rightPushAll(key, value);
495             if (time > 0) {
496                 expire(key, time);
497             }
498             return true;
499         } catch (Exception e) {
500             e.printStackTrace();
501             return false;
502         }
503     }
504 
505     /**
506      * 根據索引修改list中的某條資料
507      * @param key 鍵
508      * @param index 索引
509      * @param value 值
510      * @return
511      */
512     public boolean lUpdateIndex(String key, long index,Object value) {
513         try {
514             redisTemplate.opsForList().set(key, index, value);
515             return true;
516         } catch (Exception e) {
517             e.printStackTrace();
518             return false;
519         }
520     }
521 
522     /**
523      * 移除N個值為value
524      * @param key 鍵
525      * @param count 移除多少個
526      * @param value 值
527      * @return 移除的個數
528      */
529     public long lRemove(String key,long count,Object value) {
530         try {
531             Long remove = redisTemplate.opsForList().remove(key, count, value);
532             return remove;
533         } catch (Exception e) {
534             e.printStackTrace();
535             return 0;
536         }
537     }
538 
539 }

4、配置檔案中新增redis的配置項

# Redis資料庫索引(預設為0)
spring.redis.database=0
# Redis伺服器地址
spring.redis.host=127.0.0.1
# Redis伺服器連線埠
spring.redis.port=6379
# Redis伺服器連線密碼(預設為空)
spring.redis.password=
#連線池最大連線數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連線池中的最大空閒連線
spring.redis.pool.max-idle=8
# 連線池中的最小空閒連線
spring.redis.pool.min-idle=0
# 連線超時時間(毫秒)
spring.redis.timeout=300

以上內容配置內容就完成了。接下來通過Controller來驗證redis相關配置

1、控制器中增加如下程式碼:

 1 package com.yl.demo.controller;
 2 
 3 import com.yl.demo.bean.userinfo;
 4 import com.yl.demo.service.userinfoService;
 5 import com.yl.demo.utils.RedisUtil;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.web.bind.annotation.RequestMapping;
 8 import org.springframework.web.bind.annotation.RestController;
 9 
10 import javax.annotation.Resource;
11 import java.util.List;
12 
13 @RestController
14 @RequestMapping("user")
15 public class UsersController {
16     @Autowired
17     userinfoService userinfoService;
18     private static int ExpireTime = 60;   // redis中儲存的過期時間60s
19     @Resource
20     private RedisUtil redisUtil;
21 
22     @RequestMapping("demo")
23     public String demo(){
24         List<userinfo> list=userinfoService.selectAlluserinfo();
25         list.stream().forEach(System.out::print);
26         return  list.toString()+".";
27     }
28 
29     @RequestMapping("set")
30     public boolean redisset(String key, String value){
31         //return redisUtil.set(key,userEntity,ExpireTime);
32         return redisUtil.set(key,value);
33     }
34 
35     @RequestMapping("get")
36     public Object redisget(String key){
37         return redisUtil.get(key);
38     }
39 
40     @RequestMapping("expire")
41     public boolean expire(String key){
42         return redisUtil.expire(key,ExpireTime);
43     }
44 }

2、通過瀏覽器訪問http://localhost:8080/user/set?key=redis&value=redis

  此方法是寫入redis內容,key為redis,值為redis值

3、我們通過get方式獲取下上一個方法寫入到redis的值,看是否正常

訪問http://localhost:8080/user/get?key=redis,頁面顯示如下,表示成功

至此,redis就整合到spring boot中了,可以盡情使用了。