Redis-SpringBoot整合(註解和模板)

參考博客:http://www.cnblogs.com/ashleyboy/p/9595584.htmlhtml

參考學習網站:how2java.cnjava

 

SpringBoot中使用Redis的兩種方式:RedisTemplate,   註解redis

 

這裏使用的是IDEA, 項目爲maven風格的SpringBootspring

 

一.pom.xml依賴:數據庫

添加Redis依賴和JPA依賴數組

這裏我開始犯了個錯誤,就是沒有依賴jpa包,致使沒法使用RedisTemplate類緩存

        <!--Redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- jpa-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

 

二.application.propertiesspringboot

在application.properties中添加Redis數據庫的配置信息,使得能夠訪問Redis數據庫服務器

################################Redis配置##################################
#Redis數據庫索引
spring.redis.database=0
#Redis服務器地址
spring.redis.host=127.0.0.1
#Redis服務器鏈接端口
spring.redis.port=6379
#Redis服務器鏈接密碼
spring.redis.password=
#鏈接池最大鏈接數
spring.redis.jedis.pool.max-active=20
#鏈接池中的最大空閒鏈接
spring.redis.jedis.pool.min-idle=5
#鏈接超時時間(毫秒)
spring.redis.timeout=2000

 

_________________________________________________________________________數據結構

經過Redis進行數據緩存的方式有兩種,

    一種是使用Redis模板進行數據緩存,
    一種是經過註解,讓Spring框架自動進行數據緩存

 

首先是第一種, 使用RedisTemplate編寫RedisUtil工具,來進行數據緩存操做

三.使用RedisTemplate模板進行數據操做

完成上面的配置以後,其實就能夠直接使用RedisTemplate模板操做數據了

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class SpringbootApplicationTests {
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void contextLoads() {
        stringRedisTemplate.opsForValue().set("test","123");
        String test = stringRedisTemplate.opsForValue().get("test");
        System.out.println(test);
    }
}

 

四.自定義RedisTemplate

若使用默認的RedisTemplate配置,其泛型爲RedisTemplate<Object,Object>, 不方便保存對象

這時就要自定義模板和序列化處理程序,使得Redis可以保存對象

    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(factory);//設置連接工廠

        RedisSerializer stringSerializer = new StringRedisSerializer();//初始化string序列化器
        redisTemplate.setKeySerializer(stringSerializer);//設置key使用string序列化方式
        redisTemplate.setHashKeySerializer(stringSerializer);//設置哈希鍵使用string的序列化方式

        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(默認使用JDK的序列化方式)
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //初始化jackson序列化方式

        ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修飾符範圍,ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.PUBLIC_ONLY);
        // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,好比String,Integer等會跑出異常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);//設置
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        
        return redisTemplate;
    }

 

五.自定義RedisUtil

在完成上面的自定義配置後,就可使用RedisTemplate來寫操做Redis的工具了

此段參考:https://www.jianshu.com/p/b9154316227e

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

 

測試一下其中的一些方法:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class SpringbootApplicationTests {
    @Autowired
    private RedisUtil redisUtil;

    @Test
    public void contextLoads() {
//        Category category = new Category();
//        category.setId(1);
//        category.setName("lala");
//        redisUtil.lSet("list",category);
        Category c = (Category)redisUtil.lGetIndex("list",2);
        System.out.println(c);
    }
}

這裏先是將Category類經過lSet()方法保存到Redis中,其鍵位"list"

而後經過lGetIndex()方法,獲取這個對象,並強轉爲Category,從而得到結果

Category[id=1,name=lala]

固然也能夠經過Redis客戶端,檢查是否有這個數據

127.0.0.1:6379> lrange list 0 3
1) "\"redis\""
2) "\"redis\""
3) "[\"com.springboottest.springboot.pojo.Category\",{\"id\":1,\"name\":\"lala\"}]"

 

參考:http://www.cnblogs.com/ashleyboy/p/9595584.html

StringRedisTemplate是Spring Boot內置的操做Redis的API實現類,另外還有一個API實現類是RedisTemplate。StringRedisTemplate的API假定全部的數據類型化都是字符類型,即key和value都是字符串類型,對於常見額SpringBoot應用系統,使用字符串操做也已經足夠了,並且能方便的經過客戶端管理工具管理。StringRedisTemplate繼承RedisTemplate,與RedisTemplate不一樣的是從新設置了序列化策略,使用StringRedisSerialier類來序列化key-value,包括List、Hash、Set等數據結構。

 

_________________________________________________________________________________________

除了使用Redis模板進行緩存外,還能夠經過指定Spring Cache緩存支持,經過註解進行緩存

 

六.自定義CacheManager

經過配置Spring的CacheManager爲Redis,來指定Redis作緩存

構造RedisCacheManager的方法有兩種

一種是靜態方法create得到 Spring默認配置的CacheManager

@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
    RedisCacheManager cacheManager = RedisCacheManager.create(factory);
    return cacheManager;
}

另外一種是經過RedisCacheManager構建器→builder(factory)方法,進行自定義配置後得到

RedisCacheManager cacheManager = RedisCacheManager.builder(factory) 
                .initialCacheNames(cacheNames)
                .withInitialCacheConfigurations(configmap) 
                .build();

 此處給出完整代碼:

    @Bean
public CacheManager cacheManager(RedisConnectionFactory factory){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//生成一個默認配置,經過config對象便可對緩存進行自定義配置
config = config.entryTtl(Duration.ofMinutes(1)) //經過Duration,設置緩存的過時時間爲1分鐘
.disableCachingNullValues()//不緩存空值
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))//設置key序列化器
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()));//設置value序列化器


RedisCacheManager cacheManager = RedisCacheManager.builder(factory) //使用自定義的緩存配置初始化cacheManager
.cacheDefaults(config)
.build();
//RedisCacheManager redisCacheManager = RedisCacheManager.create(factory);
return cacheManager;
}
    private RedisSerializer<String> keySerializer(){
        return new StringRedisSerializer();
    }

    private RedisSerializer<Object> valueSerializer(){
        return new Jackson2JsonRedisSerializer(Object.class);
    }

 

七.在SpringBoot的主程序中加入@EnableCaching開啓緩存

@SpringBootApplication
@EnableCaching
public class SpringbootApplication  {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }

}

 

如下爲操做示例:

八.準備一個實體類,Mapper和Service

1.實體類

package com.springboottest.springboot.pojo;

public class Person {
    private long id;
    private String name;
    private long age;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getAge() {
        return age;
    }

    public void setAge(long age) {
        this.age = age;
    }

    @Override
    public String toString(){
        return "Person[id="+id+",name="+name+",age="+age+"]";
    }
}

2.Mapper

@Mapper
@Component("personmapper")
public interface PersonMapper {

    @Insert("insert into person_ (name,age) values(#{name},#{age})")
    public int add(Person person);

    @Select("select * from person_ where id = #{id}")
    public Person get(long id);

}

3.Service

@Service
@CacheConfig(cacheNames = "person")
public class PersonService {
    @Autowired
    private PersonMapper personMapper;

    @Cacheable(cacheNames = "person1" ,key="#root.methodName+'['+#id+']'")
    public Person getPersonById(long id){
        Person person = personMapper.get(id);
        return person;
    }

}

 

九.準備 person_表

create table blood_(
id BIGINT(11) PRIMARY key auto_increment,
name VARCHAR(30) not null,
age BIGINT(11) not null
)ENGINE=INNODB

本人數據庫學得很差....這裏就隨便寫的數據建的

 

十.調用service中的getPersonById

經過調用service中的getPersonById, 從數據庫中得到Person的數據, 而後Spring框架會自動緩存數據到Redis中

這裏我用RedisClient界面查看的數據

能夠看到緩存後,保存到了Redis中的person1下

key爲person1::getPersonBtId[1]

value爲保存在數據庫中的數值

相關文章
相關標籤/搜索