springboot實現redis緩存

Redis可以存儲鍵與5種不同數據結構類型之間的映射,這5種數據結構類型分別爲String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。

下面來對這5種數據結構類型作簡單的介紹:

結構類型 結構存儲的值 結構的讀寫能力
String 可以是字符串、整數或者浮點數 對整個字符串或者字符串的其中一部分執行操作;對象和浮點數執行自增(increment)或者自減(decrement)
List 一個鏈表,鏈表上的每個節點都包含了一個字符串 從鏈表的兩端推入或者彈出元素;根據偏移量對鏈表進行修剪(trim);讀取單個或者多個元素;根據值來查找或者移除元素
Set 包含字符串的無序收集器(unorderedcollection),並且被包含的每個字符串都是獨一無二的、各不相同 添加、獲取、移除單個元素;檢查一個元素是否存在於某個集合中;計算交集、並集、差集;從集合裏賣弄隨機獲取元素
Hash 包含鍵值對的無序散列表 添加、獲取、移除單個鍵值對;獲取所有鍵值對
Zset 字符串成員(member)與浮點數分值(score)之間的有序映射,元素的排列順序由分值的大小決定 添加、獲取、刪除單個元素;根據分值範圍(range)或者成員來獲取元素

使用Jedis操作redis

首先要在pom文件中引入依賴:

		<!-- jedis -->
	    <dependency>
		    <groupId>redis.clients</groupId>
		    <artifactId>jedis</artifactId>
		    <version>2.8.2</version>
	    </dependency>

然後就可以使用jedis操作redis數據庫了

代碼如下:

package com.help.demo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.junit.Before;
import org.junit.Test;

import redis.clients.jedis.Jedis;


public class JedisClient {
	
	
	private Jedis jedis; 
	
	@Before
	public void testConnRedis() {
		
		//連接redis ,redis的默認端口是6379  localhost也可以替換成目標IP

		  jedis = new Jedis ("localhost",6379); 
		//權限認證 如果有密碼 需要加上權限認證 如果沒有可以忽略
       //  jedis.auth("admin"); 
	}
	/**
     * redis存儲字符串
     */
    @Test
    public void testString() {
	       //-----添加數據----------  
	        jedis.set("name","xiaobai");//向key-->name中放入了value-->xiaobai 
	        System.out.println(jedis.get("name"));//執行結果:xiaobai  
	        
	      //將值value關聯到key,並將key的生存時間設爲seconds(秒)。 
	        jedis.setex("foo", 5, "haha"); 
	        System.out.println(jedis.get("foo"));
	        
	        
	      //拼接 
	        jedis.append("name", " is my friend"); 
	        System.out.println(jedis.get("name")); 
        
	      //返回key的個數 
	        System.out.println(jedis.dbSize());
      
            jedis.del("name");  //刪除某個鍵 //可以添加多個 jedis.del("key1","key2","key3","key4","key5");
            System.out.println(jedis.get("name"));
         
         
         //檢查給定key是否存在 因爲上面刪除了 所以不存在
            Boolean boo = jedis.exists("name"); 
            System.out.println(boo);
         
        
          //設置多個鍵值對
            jedis.mset("name","xiaoer","age","23","qq","476777XXX");
          //jedis.incr("age"); //進行加1操作
            System.out.println(jedis.get("name") + "-" + jedis.get("age") + "-" + jedis.get("qq"));
        
	      //將key改名爲newkey,當key和newkey相同或者key不存在時,返回一個錯誤
	        jedis.rename("name", "name2");
	        System.out.println(jedis.get("name2"));
	        
	      //返回key所儲存的值的類型。 
	      //none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表) 
	         System.out.println(jedis.type("name2"));
      
      
      
	      //設置key生存時間,當key過期時,它會被自動刪除。 
	         jedis.expire("name2", 10);//5秒過期 
        
        
          //移除給定key的生存時間(設置這個key永不過期)
         	 jedis.persist("name2"); 
        
          //清空所有的key
         	//jedis.flushAll();
         	 
          //哈希表key中的域field的值設爲value。 
         	/*jedis.hset("key1", "field1", "field1-value"); 
         	jedis.hset("key1", "field2", "field2-value"); 
         	jedis.hset("key1", "field3", "field3-value");*/
         	//和上面同樣的功能
         	Map<String, String> map = new HashMap<String, String>(); 
         	map.put("field1", "field5-value"); 
         	map.put("field2", "field6-value"); 
         	jedis.hmset("key1", map);
         	
         	//返回哈希表key中給定域field的值 
         	System.out.println(jedis.hget("key1", "field1"));
         	
         	//返回哈希表key中給定域field的值(多個)
         	List<?> list = jedis.hmget("key1","field1","field2"); 
         	for(int i=0;i<list.size();i++){ 
         	   System.out.println(list.get(i)); 
         	} 
         	
         	//刪除哈希表key中的一個或多個指定域
         	//jedis.hdel("key1", "field1");
         	//jedis.hdel("key1", "field1","field2");
         	
         	//查看哈希表key中,給定域field是否存在。 
         	System.out.println(jedis.hexists("key1", "field1"));
         	
         	//返回哈希表key中所有域和值
         	Map<String,String> map2 = jedis.hgetAll("key1"); 
         	for(Map.Entry entry: map2.entrySet()) { 
         	   System.out.print(entry.getKey() + ":" + entry.getValue() + "\t"); 
         	}
         	
         	//返回哈希表key中的所有map集合的key值
         	System.out.println(jedis.hkeys("key1"));
         	
         	//返回哈希表key中的所有map集合的value值
         	System.out.println(jedis.hvals("key1"));
         	
         	//查詢key值對應的集合長度
         	System.out.println(jedis.llen("key2"));
         	//刪除redis中的list集合
         	for (int i = 0; i < jedis.llen("key2"); i++) {
         			System.out.println(jedis.lpop("key2")+"刪除");
			}
        	//將值value插入到列表key的表頭。  在key對應 list的頭部添加字符串元素  如果沒有key值 那就新建一個key值然後建立list列表保存到redis 中
         	jedis.lpush("key2", "value1-0");
         	jedis.lpush("key2", "value1-1"); 
         	jedis.lpush("key2", "value1-2");
         	
         	//在key對應 list 的尾部添加字符串元素
         	//jedis.rpush("key2", "value1-2");
         	
         	
         	//返回列表key中指定區間內的元素,區間以偏移量start和stop指定.
         	//下標(index)參數start和stop從0開始;
         	//負數下標代表從後開始(-1表示列表的最後一個元素,-2表示列表的倒數第二個元素,以此類推)
         	List<String> list2 = jedis.lrange("key2", 0, -1);//stop下標也在取值範圍內(閉區間)
         	for(int i=0;i<list2.size();i++){ 
         	   System.out.println(list2.get(i)); 
         	} 
         	
         	
         	//set集合--------------------------
         	//將member元素加入到集合key當中。  
         	jedis.sadd("key3", "value5"); 
         	jedis.sadd("key3", "value8");

         	//移除集合中的member元素。 
         //	jedis.srem("key3", "value5"); 
         	
         	//返回集合key中的所有成員。 
         	Set set = jedis.smembers("key3"); 
         	
            System.out.println(set.toString());
            
          //判斷元素是否是集合key的成員
            System.out.println(jedis.sismember("key3", "value2"));
         	
          //返回一個集合的全部成員,該集合是所有給定集合的交集
           Set set2 = jedis.sinter("key3","key2");
            System.out.println(set2.toString());
    }
}

===========================================================

springboot操作redis之引入連接池:

首先,建立連接池然後通過獲取連接池連接redis(默認已經引入jedis依賴)
連接池工具類如下:

package com.chaoju.config;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public final class RedisUtil {
    
    //Redis服務器IP
    private static String ADDR = "localhost";
    
    //Redis的端口號
    private static int PORT = 6379;
    
    //訪問密碼
     private static String AUTH = "admin";
    
    //可用連接實例的最大數目,默認值爲8;
    //如果賦值爲-1,則表示不限制;如果pool已經分配了maxActive個jedis實例,則此時pool的狀態爲exhausted(耗盡)。
    private static int MAX_ACTIVE = 1024;
    
    //控制一個pool最多有多少個狀態爲idle(空閒的)的jedis實例,默認值也是8。
    private static int MAX_IDLE = 200;
    
    //等待可用連接的最大時間,單位毫秒,默認值爲-1,表示永不超時。如果超過等待時間,則直接拋出JedisConnectionException;
    private static int MAX_WAIT = 10000;
    
    private static int TIMEOUT = 10000;
    
    //在borrow一個jedis實例時,是否提前進行validate操作;如果爲true,則得到的jedis實例均是可用的;
    private static boolean TEST_ON_BORROW = true;
    
    private static JedisPool jedisPool = null;
    
    /**
     * 初始化Redis連接池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxActive(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWait(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT);
            //如果redis有密碼 就使用下面這個語句  沒有就使用上面這個
            // jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 獲取Jedis實例
     * @return
     */
    public synchronized static Jedis getJedis() {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                return resource;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 釋放jedis資源
     * @param jedis
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedisPool.returnResource(jedis);
        }
    }
    public static void main(String[] args) {
    	getJedis();
	}
   
}

然後將上面的jedis連接的語句

 jedis = new Jedis ("localhost",6379); 
 jedis.auth("admin"); 

換成

 jedis =  RedisUtil.getJedis();

如此也可以操作redis!!!

===============================================================================================

springboot使用配置文件操作redis之引入連接池:

首先在配置文件中添加redis的配置(默認已添加jedis依賴):



#redis jedis配置
# 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=200
# 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
# 連接池中的最大空閒連接
spring.redis.pool.max-idle=8
# 連接池中的最小空閒連接
spring.redis.pool.min-idle=0
# 連接超時時間(毫秒)
spring.redis.timeout=0
#spring-session 使用
spring.session.store-type=none

然後添加配置類:

package com.example.demo.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class JedisConfig extends CachingConfigurerSupport{
    private Logger logger = LoggerFactory.getLogger(JedisConfig.class);

    /**
     * SpringSession  需要注意的就是redis需要2.8以上版本,然後開啓事件通知,在redis配置文件裏面加上
     * notify-keyspace-events Ex
     * Keyspace notifications功能默認是關閉的(默認地,Keyspace 時間通知功能是禁用的,因爲它或多或少會使用一些CPU的資源)。
     * 或是使用如下命令:
     * redis-cli config set notify-keyspace-events Egx
     * 如果你的Redis不是你自己維護的,比如你是使用阿里雲的Redis數據庫,你不能夠更改它的配置,那麼可以使用如下方法:在applicationContext.xml中配置
     * <util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>
     * @return
     */

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.pool.max-active}")
    private int maxActive;

    @Value("${spring.redis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.pool.max-wait}")
    private long maxWaitMillis;



    @Bean
    public JedisPool redisPoolFactory(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisPoolConfig.setMinIdle(minIdle);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,null);

        logger.info("JedisPool注入成功!");
        logger.info("redis地址:" + host + ":" + port);
        return  jedisPool;
    }

}

這時啓動程序後在控制檯會出現配置類中打印的日誌
在這裏插入圖片描述

接着添加普通類 使用jedis的連接池:

package com.example.demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;


@RestController
public class Tests {

	@Autowired
	private JedisPool jedisPool;
	
	@RequestMapping("/")
	public String set() {
		//獲取redis實例
		 Jedis resource = jedisPool.getResource();
		 String str = resource.get("age");
		 System.out.println(str);
		 return str;
	    }
}

啓動項目並訪問http://localhost:8080/當頁面返回數據表示成功
在這裏插入圖片描述

==================================================================

使用Redistemplate操作redis數據庫

Spring封裝了RedisTemplate對象來進行對Redis的各種操作,它支持所有的Redis原生的api。RedisTemplate位於spring-data-redis包下。

RedisTemplate中定義了對5種數據結構操作:

redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set

StringRedisTemplate與RedisTemplate

1.兩者的關係是StringRedisTemplate繼承RedisTemplate。
2.兩者的數據是不共通的;也就是說StringRedisTemplate只能管理StringRedisTemplate裏面的數據,RedisTemplate只能管理RedisTemplate中的數據。
3.SDR默認採用的序列化策略有兩種,一種是String的序列化策略,一種是JDK的序列化策略。
----StringRedisTemplate默認採用的是String的序列化策略,保存的key和value都是採用此策略序列化保存的。
----RedisTemplate默認採用的是JDK的序列化策略,保存的key和value都是採用此策略序列化保存的。

操作步驟:

首先添加redis依賴:

  <!-- springboot整合redis -->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-redis</artifactId>  
        </dependency> 

然後添加配置類(默認配置文件properties已經添加好):

package com.example.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * redis配置類
 *
 **/
@Configuration
@EnableCaching//開啓註解
public class RedisConfig {
   /**
     * 選擇redis作爲默認緩存工具
     * @param redisTemplate
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
        CacheManager cacheManager = new RedisCacheManager(redisTemplate);
        return cacheManager;
        /*RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
        // 多個緩存的名稱,目前只定義了一個
        rcm.setCacheNames(Arrays.asList("thisredis"));
        //設置緩存默認過期時間(秒)
        rcm.setDefaultExpiration(600);
        return rcm;*/
    }
   /**
     * retemplate相關配置
     * @param factory
     * @return
     */
    // 以下兩種redisTemplate自由根據場景選擇
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        // 配置連接工廠
        template.setConnectionFactory(connectionFactory);

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

        ObjectMapper mapper = new ObjectMapper();
          // 指定要序列化的域,field,get和set,以及修飾符範圍,ANY是都有包括private和public
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化輸入的類型,類必須是非final修飾的,final修飾的類,比如String,Integer等會跑出異常
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
		 // 值採用json序列化
        template.setValueSerializer(serializer);
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }
}

接着就可以使用了,使用方式如下

添加redis操作String數據結構 的類:

package com.example.demo.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class Tests {

	@Autowired
    private RedisTemplate<String, String> redisTemplate;
    // private RedisTemplate<String, Object> redisTemplate;根據實際情況取泛型
	
	
	String str = null;
	
	@RequestMapping("/String")
	public void sets(){
		//set void set(K key, V value); 以key-value的形式保存字符串類的數據
		 redisTemplate.opsForValue().set("names", "劉德華");
		//get V get(Object key); 獲取指定key值的數據 
		  str =  redisTemplate.opsForValue().get("names");
		  System.out.println(str);
		  
		//setIfAbsent Boolean setIfAbsent(K key, V value); 如果key值之前已經存在爲 false  如果之前不存在則爲 true  
		  System.out.println(redisTemplate.opsForValue().setIfAbsent("names","劉德華22"));
		  
		  
		//set void set(K key, V value, long timeout, TimeUnit unit);爲緩存設置時間
		  redisTemplate.opsForValue().set("name3","張學友",10, TimeUnit.SECONDS);
		  //由於設置的是10秒失效,十秒之內查詢有結果,十秒之後返回爲null
		  System.out.println(redisTemplate.opsForValue().get("name3"));
		  
		 // set void set(K key, V value, long offset);
		 // 覆寫(overwrite)給定 key 所儲存的字符串值,從偏移量 offset 開始
		  redisTemplate.opsForValue().set("name4","hello world");
		  redisTemplate.opsForValue().set("name4","redis", 6);
		  //輸出結果 hello redis
		  System.out.println(redisTemplate.opsForValue().get("name4"));
		  
		  //getAndSet V getAndSet(K key, V value);   設置鍵的字符串值並返回其舊值
		  redisTemplate.opsForValue().set("getSetTest","test");
		  //結果:test
		  System.out.println(redisTemplate.opsForValue().getAndSet("getSetTest","test2"));
		  
		  //append Integer append(K key, String value);
		  //如果key已經存在並且是一個字符串,則該命令將該值追加到字符串的末尾。如果鍵不存在,則它被創建並設置爲空字符串,因此APPEND在這種特殊情況下將類似於SET。
		  redisTemplate.opsForValue().append("test","Hello");
		  System.out.println(redisTemplate.opsForValue().get("test"));
		  redisTemplate.opsForValue().append("test","world");
		  System.out.println(redisTemplate.opsForValue().get("test"));
		  
		  //size Long size(K key); 返回key所對應的value值得長度
		  System.out.println("***************"+redisTemplate.opsForValue().size("test"));
		  
		  
		  //multiSet void multiSet(Map<? extends K, ? extends V> m);
		  //multiGet List<V> multiGet(Collection<K> keys);
		  //爲多個鍵分別設置它們的值
		  Map<String,String> maps = new HashMap<String, String>();
	      maps.put("multi1","multi4");
	      maps.put("multi2","multi5");
	      maps.put("multi3","multi6");
	      redisTemplate.opsForValue().multiSet(maps);
	      //添加多個鍵並獲取每個鍵對應的值
	      List<String> keys = new ArrayList<String>();
	      keys.add("multi1");
	      keys.add("multi2");
	      keys.add("multi3");
	      System.out.println(redisTemplate.opsForValue().multiGet(keys));//結果:[multi4, multi5, multi6]
	      
	      
	      //multiSetIfAbsent Boolean multiSetIfAbsent(Map<? extends K, ? extends V> m);
	      //爲多個鍵分別設置它們的值,如果存在則返回false,不存在返回true
	      Map<String,String> maps1 = new HashMap<String, String>();
	      maps1.put("multi11","multi11");
	      maps1.put("multi22","multi22");
	      maps1.put("multi33","multi33");
	      Map<String,String> maps2 = new HashMap<String, String>();
	      maps2.put("multi1","multi1");
	      maps2.put("multi2","multi2");
	      maps2.put("multi3","multi3");
	      System.out.println(redisTemplate.opsForValue().multiSetIfAbsent(maps1));//true
	      System.out.println(redisTemplate.opsForValue().multiSetIfAbsent(maps2)); //false
	      
	     //increment Long increment(K key, long delta); 支持整數
	      redisTemplate.opsForValue().set("increlong","2");
	      //操作increment自增時出現錯誤  JedisDataException: ERR value is not an integer or out of range
	      //所以我在redis中初始化了上面的  redisTemplate.opsForValue().set("increlong","2");數據就不報錯了 有人說是redis引入依賴版本的問題 沒找到具體原因  如果有高手幫忙指點一下
	      redisTemplate.opsForValue().increment("increlong",2);
	      System.out.println("***************"+redisTemplate.opsForValue().get("increlong"));
	      
	      //increment Double increment(K key, double delta); 支持浮點數
	      redisTemplate.opsForValue().increment("increlong",1.2);
	      System.out.println("***************"+redisTemplate.opsForValue().get("increlong"));
	    

	     // get String get(K key, long start, long end); 截取key所對應的value字符串
	      redisTemplate.opsForValue().set("appendTest", "helloworld");
	      System.out.println("*********"+redisTemplate.opsForValue().get("appendTest",0,5));
	      System.out.println("*********"+redisTemplate.opsForValue().get("appendTest",0,-1));
	      System.out.println("*********"+redisTemplate.opsForValue().get("appendTest",-3,-1));
	      
	}
   
}

添加redis操作List數據結構 的類:

package com.example.demo.config;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/list")
public class TestList {

	@Resource //這個地方之前用autowired注入報錯 換成了這個
	private RedisTemplate<String, Object> redisTemplate;
	
	/*
	 * public interface ListOperations<K,V>
	 * Redis列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素導列表的頭部(左邊)或者尾部(右邊)
	 * ListOperations專門操作list列表:
	 * */
	
	@RequestMapping("/test")
	public void TestList(){
		
		//Long leftPush(K key, V value);
		//將所有指定的值插入存儲在鍵的列表的頭部。如果鍵不存在,則在執行推送操作之前將其創建爲空列表。(從左邊插入)
		redisTemplate.opsForList().leftPush("list","java");
		redisTemplate.opsForList().leftPush("list","python");
		redisTemplate.opsForList().leftPush("list","c++");
		
		//Long leftPush(K key, V pivot, V value);
		//把value值放到key對應列表中pivot值的左面,如果pivot值存在的話
		redisTemplate.opsForList().leftPush("list","java","oc");
	    System.out.println(redisTemplate.opsForList().range("list",0,-1));
	    
	    
	          
	          
		//Long leftPushAll(K key, V... values);
		//批量把一個數組插入到列表中
		String[] stringarrays = new String[]{"1","2","3"};
		redisTemplate.opsForList().leftPushAll("listarray",stringarrays);
	    System.out.println(redisTemplate.opsForList().range("listarray",0,-1));
	    
	    
	    //Long leftPushAll(K key, Collection<V> values);
	    //批量把一個集合插入到列表中
    	  List<Object> strings = new ArrayList<Object>();
          strings.add("1");
          strings.add("2");
          strings.add("3");
          redisTemplate.opsForList().leftPushAll("listcollection4", strings);
          System.out.println(redisTemplate.opsForList().range("listcollection4",0,-1));
	    
        //Long rightPushAll(K key, V... values);
  	    String[] stringarrayss = new String[]{"1","2","3"};
  	    redisTemplate.opsForList().rightPushAll("listarrayright",stringarrayss);
          System.out.println("=oo="+redisTemplate.opsForList().range("listarrayright",0,-1));
  		  
  	    
  	    //Long rightPush(K key, V value);
  	    //將所有指定的值插入存儲在鍵的列表的頭部。如果鍵不存在,則在執行推送操作之前將其創建爲空列表。(從右邊插入)
  	    redisTemplate.opsForList().rightPush("listRight","PHP");
  	    redisTemplate.opsForList().rightPush("listRight","PB");
  	    System.out.println(redisTemplate.opsForList().range("listRight",0,-1)); 
  	    
  	    
  	    //Long rightPushAll(K key, Collection<V> values);
      	List<Object> strings2 = new ArrayList<Object>();
          strings2.add("7");
          strings2.add("8");
          strings2.add("9");
          redisTemplate.opsForList().rightPushAll("listcollectionright", strings2);
          System.out.println(redisTemplate.opsForList().range("listcollectionright",0,-1));
          
          
         //Long rightPush(K key, V pivot, V value);
         //把value值放到key對應列表中pivot值的右面,如果pivot值存在的話 如果不存在就不會保存
      	 System.out.println(redisTemplate.opsForList().range("listRight",0,-1));
      	 redisTemplate.opsForList().rightPush("listRight","PB","oc22");
         System.out.println(redisTemplate.opsForList().range("listRight",0,-1));
                
          
         //void set(K key, long index, V value);
         //在列表中index的位置設置value值
         redisTemplate.opsForList().set("listRight",1,"setValue");
         System.out.println(redisTemplate.opsForList().range("listRight",0,-1));
           
		//List<V> range(K key, long start, long end);
		//返回存儲在鍵中的列表的指定元素。偏移開始和停止是基於零的索引,其中0是列表的第一個元素(列表的頭部),1是下一個元素
		System.out.println(redisTemplate.opsForList().range("list",0,-1));
		
		//Long size(K key); 返回存儲在鍵中的列表的長度。如果鍵不存在,則將其解釋爲空列表,並返回0。當key存儲的值不是列表時返回錯誤。
		System.out.println(redisTemplate.opsForList().size("list"));
		
		
		/*Long remove(K key, long count, Object value);
		從存儲在鍵中的列表中刪除等於值的元素的第一個計數事件。
		計數參數以下列方式影響操作:
		count> 0:刪除等於從頭到尾移動的值的元素。
		count <0:刪除等於從尾到頭移動的值的元素。
		count = 0:刪除等於value的所有元素。
		 */
		System.out.println(redisTemplate.opsForList().range("listRight",0,-1));
		redisTemplate.opsForList().remove("listRight",1,"setValue");//將刪除列表中存儲的列表中第一次次出現的“setValue”。
		System.out.println(redisTemplate.opsForList().range("listRight",0,-1));
		
		//V index(K key, long index);
		//根據下表獲取列表中的值,下標是從0開始的
        System.out.println(redisTemplate.opsForList().range("listRight",0,-1));
		System.out.println(redisTemplate.opsForList().index("listRight",2));
		
		//V leftPop(K key);
		//彈出最左邊的元素,彈出之後該值在列表中將不復存在
		System.out.println(redisTemplate.opsForList().range("list",0,-1));
		System.out.println(redisTemplate.opsForList().leftPop("list"));
		System.out.println(redisTemplate.opsForList().range("list",0,-1));
		
		/*V leftPop(K key, long timeout, TimeUnit unit);
		移出並獲取列表的第一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
		用法與 leftPop(K key);一樣*/
		
		//V rightPop(K key);
		//彈出最右邊的元素,彈出之後該值在列表中將不復存在
		System.out.println(redisTemplate.opsForList().range("list",0,-1));
		System.out.println(redisTemplate.opsForList().rightPop("list"));
		System.out.println(redisTemplate.opsForList().range("list",0,-1));
		
		/*V rightPop(K key, long timeout, TimeUnit unit);
		移出並獲取列表的最後一個元素, 如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
		用法與 rightPop(K key);一樣*/
		
		//V rightPopAndLeftPush(K sourceKey, K destinationKey);
		//用於移除列表的最後一個元素,並將該元素添加到另一個列表並返回。
		System.out.println(redisTemplate.opsForList().range("list",0,-1));
		redisTemplate.opsForList().rightPopAndLeftPush("list","rightPopAndLeftPush");
		System.out.println(redisTemplate.opsForList().range("list",0,-1));
		System.out.println(redisTemplate.opsForList().range("rightPopAndLeftPush",0,-1));
		
		/*V rightPopAndLeftPush(K sourceKey, K destinationKey, long timeout, TimeUnit unit);
		用於移除列表的最後一個元素,並將該元素添加到另一個列表並返回,如果列表沒有元素會阻塞列表直到等待超時或發現可彈出元素爲止。
		用法與rightPopAndLeftPush(K sourceKey, K destinationKey)一樣*/
		
	}
}

添加Hash數據結構 的操作:

package com.example.demo.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hash")
public class TestHash {

	@Resource
	private RedisTemplate<String, Object> redisTemplate;
	
	@RequestMapping("/test")
	public void TestHashs(){
		//添加redis
		Map<String,Object> testMap = new HashMap<String,Object>();
	    testMap.put("name","wang");
	    testMap.put("age",27);
	    testMap.put("tel","13000000000");
	    redisTemplate.opsForHash().putAll("redisHash1",testMap);
	    
	    
	    //void put(H key, HK hashKey, HV value);
	    //設置散列hashKey的值
	    redisTemplate.opsForHash().put("redisHash1","address","北京市豐臺區");
	    System.out.println(redisTemplate.opsForHash().entries("redisHash1"));
	    
	    //List<HV> multiGet(H key, Collection<HK> hashKeys);
	    //從哈希中獲取給定hashKey的值
	    List<Object> kes = new ArrayList<Object>();
	    kes.add("name");
	    kes.add("age");
	    System.out.println(redisTemplate.opsForHash().multiGet("redisHash1",kes));
	    
	    //Set<HK> keys(H key);
	    //獲取key所對應的散列表的key
	    System.out.println(redisTemplate.opsForHash().keys("redisHash1"));
	      
	    //Long size(H key);
	    //獲取key所對應的散列表的大小個數
	    System.out.println(redisTemplate.opsForHash().size("redisHash1"));
	      
	    //HV get(H key, Object hashKey);
	    //從鍵中的哈希獲取給定hashKey的值
	    System.out.println(redisTemplate.opsForHash().get("redisHash1","age"));
	    
	    
	    //Map<HK, HV> entries(H key);
	    //獲取整個哈希存儲的key值根據密鑰
	    System.out.println(redisTemplate.opsForHash().entries("redisHash1"));
	    
	    //List<HV> values(H key);
	    //獲取整個哈希存儲的value值根據密鑰
	    System.out.println(redisTemplate.opsForHash().values("redisHash1"));
	    
	    //Boolean hasKey(H key, Object hashKey);
	    //確定哈希hashKey是否存在
	    System.out.println(redisTemplate.opsForHash().hasKey("redisHash1","age"));
	    System.out.println(redisTemplate.opsForHash().hasKey("redisHash1","ttt"));
	    
	    //Long delete(H key, Object... hashKeys);
	    //刪除給定的哈希hashKeys
	    redisTemplate.opsForHash().delete("redisHash1","name");
	    System.out.println(redisTemplate.opsForHash().entries("redisHash1"));
	    
	    
	    //Boolean putIfAbsent(H key, HK hashKey, HV value);
	    //僅當hashKey不存在時才設置散列hashKey的值。
	    System.out.println(redisTemplate.opsForHash().putIfAbsent("redisHash1","age",30));
	    System.out.println(redisTemplate.opsForHash().putIfAbsent("redisHash1","kkk","kkk"));
	    
	}
	
}

添加redis操作set數據結構 的類

package com.example.demo.config;

import javax.annotation.Resource;

import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/set")
public class TestSet {

	/**
	 * Redis的Set是string類型的無序集合。集合成員是唯一的,這就意味着集合中不能出現重複的數據。
	 *	Redis 中 集合是通過哈希表實現的,所以添加,刪除,查找的複雜度都是O(1)。
	 *	public interface SetOperations<K,V>
	 *	SetOperations提供了對無序集合的一系列操作:
	 */
	@Resource
	private RedisTemplate<String, Object> redisTemplate;
	
	@RequestMapping("/test")
	public void TestSets(){
		
		//Long add(K key, V... values);
		//無序集合中添加元素,返回添加個數
		//或者可以直接在add裏面添加多個值 如:template.opsForSet().add("setTest","123","456")
		String[] strarrays = new String[]{"strarr1","sgtarr2","sgtarr3"};
		System.out.println(redisTemplate.opsForSet().add("setTest", strarrays));
		
		//Set<V> distinctRandomMembers(K key, long count);
		//獲取多個key無序集合中的元素(去重),count表示個數
		System.out.println("randomMembers:" + redisTemplate.opsForSet().distinctRandomMembers("setTest",5));
		
		//List<V> randomMembers(K key, long count);
		//獲取多個key無序集合中的元素(不去重),count表示個數
		System.out.println("randomMembers:" + redisTemplate.opsForSet().randomMembers("setTest",5));
		
		
		//Cursor<V> scan(K key, ScanOptions options);
		//遍歷set
		Cursor<Object> curosr = redisTemplate.opsForSet().scan("setTest", ScanOptions.NONE);
	      while(curosr.hasNext()){
	          System.out.println(curosr.next());
	      }
		//V randomMember(K key);
		//隨機獲取key無序集合中的一個元素
	    System.out.println("setTestrandomMember:" + redisTemplate.opsForSet().randomMember("setTest"));
	    System.out.println("setTestrandomMember:" + redisTemplate.opsForSet().randomMember("setTest"));
	    System.out.println("setTestrandomMember:" + redisTemplate.opsForSet().randomMember("setTest"));
	    System.out.println("setTestrandomMember:" + redisTemplate.opsForSet().randomMember("setTest"));
	
		//Boolean move(K key, V value, K destKey);
		//將 member 元素從 source 集合移動到 destination 集合
		redisTemplate.opsForSet().move("setTest","strarr1","setTest2");
		System.out.println(redisTemplate.opsForSet().members("setTest"));
		System.out.println(redisTemplate.opsForSet().members("setTest2"));
		
		//Boolean isMember(K key, Object o);
		//判斷 member 元素是否是集合 key 的成員
		System.out.println(redisTemplate.opsForSet().isMember("setTest","ccc"));
		
		//Long size(K key);
		//無序集合的大小長度
		System.out.println(redisTemplate.opsForSet().size("setTest"));
		
		
		//Set<V> members(K key);
		//返回集合中的所有成員
		System.out.println(redisTemplate.opsForSet().members("setTest"));
		
		//V pop(K key);
		//移除並返回集合中的一個隨機元素
		System.out.println(redisTemplate.opsForSet().pop("setTest"));
		System.out.println(redisTemplate.opsForSet().members("setTest"));
		
		//Long remove(K key, Object... values);
		//移除集合中一個或多個成員
		String[] strarrays1 = new String[]{"strarr1","sgtarr2"};
		System.out.println(redisTemplate.opsForSet().remove("setTest",strarrays1));
	}
	
}

添加redis操作ZSet數據結構 的類:

package com.example.demo.config;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Redis有序集合和無序集合一樣也是string類型元素的集合,且不允許重複的成員。
 *不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來爲集合中的成員進行從小到大的排序。
 *有序集合的成員是唯一的,但分數(score)卻可以重複。
 */

@RestController
@RequestMapping("/zset")
public class TestZSet {

	@Resource
	private RedisTemplate<String, Object> redisTemplate;
	
	@RequestMapping("/test")
	public void Zset(){
		
		//Boolean add(K key, V value, double score);
		//新增一個有序集合,存在的話爲false,不存在的話爲true
		System.out.println(redisTemplate.opsForZSet().add("zset1","zset-1",1.0));
		System.out.println(redisTemplate.opsForZSet().add("zset1","zset-2",3.0));
		
		//Long add(K key, Set<TypedTuple<V>> tuples);
		//新增一個有序集合 並返回添加個數
		ZSetOperations.TypedTuple<Object> objectTypedTuple1 = new DefaultTypedTuple<Object>("zset-5",9.6);
		ZSetOperations.TypedTuple<Object> objectTypedTuple2 = new DefaultTypedTuple<Object>("zset-6",9.9);
		Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<ZSetOperations.TypedTuple<Object>>();
		tuples.add(objectTypedTuple1);
		tuples.add(objectTypedTuple2);
		System.out.println(redisTemplate.opsForZSet().add("zset1",tuples));
		System.out.println(redisTemplate.opsForZSet().range("zset1",0,-1));
		
		//Cursor<TypedTuple<V>> scan(K key, ScanOptions options);
		//遍歷zset
		Cursor<ZSetOperations.TypedTuple<Object>> cursor = redisTemplate.opsForZSet().scan("zset1", ScanOptions.NONE);
	      while (cursor.hasNext()){
	          ZSetOperations.TypedTuple<Object> item = cursor.next();
	          System.out.println(item.getValue() + ":" + item.getScore());
	      }
	      
        //Long zCard(K key);
        //獲取有序集合的成員個數
        System.out.println(redisTemplate.opsForZSet().zCard("zset1"));
        
        //Long size(K key);
        //獲取有序集合的成員數,內部調用的就是zCard方法
        System.out.println(redisTemplate.opsForZSet().size("zset1"));
        
        
        //Long count(K key, double min, double max);
        //通過分數返回有序集合指定區間內的成員個數
        System.out.println(redisTemplate.opsForZSet().count("zset1",0,9.7));
        
        
        //Double score(K key, Object o);
        //獲取指定成員的score值
        System.out.println("-oo-"+redisTemplate.opsForZSet().score("zset1","zset-2"));
		
		//Double incrementScore(K key, V value, double delta);
		//增加元素的score值,並返回增加後的值
		System.out.println(redisTemplate.opsForZSet().incrementScore("zset1","zset-1",1.1));  //原爲1.1
		
		//Long rank(K key, Object o);
		//返回有序集中指定成員的排名,其中有序集成員按分數值遞增(從小到大)順序排列(從0開始) 如果沒有返回null
		System.out.println(redisTemplate.opsForZSet().rank("zset1","zset-6"));
		
		//Long reverseRank(K key, Object o);
		//返回有序集中指定成員的排名,其中有序集成員按分數值遞減(從大到小)順序排列
		 System.out.println(redisTemplate.opsForZSet().reverseRank("zset1","zset-6"));
		 
	    //Set<V> range(K key, long start, long end);
		//通過索引區間返回有序集合成指定區間內的成員,其中有序集成員按分數值遞增(從小到大)順序排列
		System.out.println(redisTemplate.opsForZSet().range("zset1",0,-1));
		
		//Set<TypedTuple<V>> rangeWithScores(K key, long start, long end);
		//通過索引區間返回有序集合成指定區間內的成員對象,其中有序集成員按分數值遞增(從小到大)順序排列
		Set<ZSetOperations.TypedTuple<Object>> tuples1 = redisTemplate.opsForZSet().rangeWithScores("zset1",0,-1);
	      Iterator<ZSetOperations.TypedTuple<Object>> iterator = tuples1.iterator();
	      while (iterator.hasNext())
	      {
	          ZSetOperations.TypedTuple<Object> typedTuple = iterator.next();
	          System.out.println("value:" + typedTuple.getValue() + "score:" + typedTuple.getScore());
	      }
		
		
		//Set<V> rangeByScore(K key, double min, double max);
		//通過分數返回有序集合指定區間內的成員,其中有序集成員按分數值遞增(從小到大)順序排列
		System.out.println(redisTemplate.opsForZSet().rangeByScore("zset1",0,5));
		
		//Set<TypedTuple<V>> rangeByScoreWithScores(K key, double min, double max);
		//通過分數返回有序集合指定區間內的成員對象,其中有序集成員按分數值遞增(從小到大)順序排列
		Set<ZSetOperations.TypedTuple<Object>> tuples2 = redisTemplate.opsForZSet().rangeByScoreWithScores("zset1",0,5);
	      Iterator<ZSetOperations.TypedTuple<Object>> iterator2 = tuples2.iterator();
	      while (iterator2.hasNext())
	      {
	          ZSetOperations.TypedTuple<Object> typedTuple = iterator2.next();
	          System.out.println("value:" + typedTuple.getValue() + "score:" + typedTuple.getScore());
	      }
	      
	      
	    //Set<V> rangeByScore(K key, double min, double max, long offset, long count);
	    //通過分數返回有序集合指定區間內的成員,並在索引範圍內,其中有序集成員按分數值遞增(從小到大)順序排列
	      System.out.println(redisTemplate.opsForZSet().rangeByScore("zset1",0,5,1,2));  
	      System.out.println(redisTemplate.opsForZSet().rangeByScore("zset1",0,5));
	      
	    //Set<TypedTuple<V>> rangeByScoreWithScores(K key, double min, double max, long offset, long count);
	    //通過分數返回有序集合指定區間內的成員對象,並在索引範圍內,其中有序集成員按分數值遞增(從小到大)順序排列
	      Set<ZSetOperations.TypedTuple<Object>> tuples3 = redisTemplate.opsForZSet().rangeByScoreWithScores("zset1",0,5,1,2);
	      Iterator<ZSetOperations.TypedTuple<Object>> iterator3 = tuples3.iterator();
	      while (iterator3.hasNext())
	      {
	          ZSetOperations.TypedTuple<Object> typedTuple = iterator3.next();
	          System.out.println("value:" + typedTuple.getValue() + "score:" + typedTuple.getScore());
	      }
	   
	      
	    //Set<V> reverseRange(K key, long start, long end);
	    //通過索引區間返回有序集合成指定區間內的成員,其中有序集成員按分數值遞減(從大到小)順序排列
	      System.out.println(redisTemplate.opsForZSet().reverseRange("zset1",0,-1));  
	      
	    //Set<TypedTuple<V>> reverseRangeWithScores(K key, long start, long end);
	    //通過索引區間返回有序集合成指定區間內的成員對象,其中有序集成員按分數值遞減(從大到小)順序排列
	      Set<ZSetOperations.TypedTuple<Object>> tuples4 = redisTemplate.opsForZSet().reverseRangeWithScores("zset1",0,-1);
	      Iterator<ZSetOperations.TypedTuple<Object>> iterator4 = tuples4.iterator();
	      while (iterator4.hasNext())
	      {
	          ZSetOperations.TypedTuple<Object> typedTuple = iterator4.next();
	          System.out.println("value:" + typedTuple.getValue() + "score:" + typedTuple.getScore());
	      }  
	      
	      
	      /*Set<V> reverseRangeByScore(K key, double min, double max);
	      與rangeByScore調用方法一樣,其中有序集成員按分數值遞減(從大到小)順序排列
	      Set<TypedTuple<V>> reverseRangeByScoreWithScores(K key, double min, double max);
	      與rangeByScoreWithScores調用方法一樣,其中有序集成員按分數值遞減(從大到小)順序排列
	      Set<V> reverseRangeByScore(K key, double min, double max, long offset, long count);
	      與rangeByScore調用方法一樣,其中有序集成員按分數值遞減(從大到小)順序排列
	      Set<TypedTuple<V>> reverseRangeByScoreWithScores(K key, double min, double max, long offset, long count);
	      與rangeByScoreWithScores調用方法一樣,其中有序集成員按分數值遞減(從大到小)順序排列*/
		
	      
	      //Long remove(K key, Object... values);
		//從有序集合中移除一個或者多個元素
		System.out.println(redisTemplate.opsForZSet().remove("zset1","zset-6"));
	    System.out.println(redisTemplate.opsForZSet().range("zset1",0,-1));
	    
	    //Long removeRange(K key, long start, long end);
	    //移除指定索引位置的成員,其中有序集成員按分數值遞增(從小到大)順序排列 如果key值不存在 返回0 代表一條也沒刪除
	    System.out.println(redisTemplate.opsForZSet().removeRange("zset1",1,2));
	    System.out.println(redisTemplate.opsForZSet().range("zset1",0,-1));
	}
	
}

然後啓動項目 並訪問相應的路徑即可!!!

==================================================================

使用註解操作redis

註解緩存的使用
@Cacheable:在方法執行前Spring先查看緩存中是否有數據,如果有數據,則直接返回緩存數據;沒有則調用方法並將方法返回值放進緩存。

@CachePut:將方法的返回值放到緩存中。

@CacheEvict:刪除緩存中的數據。

package com.example.demo.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RedisController {
	

	
	/*  @Cacheable可以標記在一個方法上,也可以標記在一個類上。
	 *  當標記在一個方法上時表示該方法是支持緩存的,當標記在一個類上時則表示該類所有的方法都是
	 *  支持緩存的。對於一個支持緩存的方法,Spring會在其被調用後將其返回值緩存起來,以保證下次
	 *  利用同樣的參數來執行該方法時可以直接從緩存中獲取結果,而不需要再次執行該方法。Spring在
	 *  緩存方法的返回值時是以鍵值對進行緩存的,值就是方法的返回結果,至於鍵的話,Spring又支持
	 *  兩種策略,默認策略和自定義策略,這個稍後會進行說明。需要注意的是當一個支持緩存的方法在
	 *  對象內部被調用時是不會觸發緩存功能的。@Cacheable可以指定三個屬性,value、key和condition。
	 * */
	 /**
     * @Cacheable 應用到讀取數據的方法上,先從緩存中讀取,如果沒有再從DB獲取數據,然後把數據添加到緩存中
     * unless 表示條件表達式成立的話不放入緩存
     */
	@RequestMapping("/item/{id}")
    @Cacheable(value = "item")
    public Item getItemById(@PathVariable int id) {
    	Item item = new Item();
    	item.setItemId(id);
    	item.setItemName("緩存1"+id);
    	
        return item;
    }
	 /**
     * @Cacheable 應用到讀取數據的方法上,先從緩存中讀取,如果沒有再從DB獲取數據,然後把數據添加到緩存中
     * unless 表示條件表達式成立的話不放入緩存
     */
	@RequestMapping("/item/all")
    @Cacheable(value = "item")
    public List<Item> getAllItem() {
		Item item1 = new Item();
    	item1.setItemId(666);
    	item1.setItemName("緩存2"+666);
    	Item item2 = new Item();
    	item2.setItemId(999);
    	item2.setItemName("緩存3"+999);
    	List<Item> items=new ArrayList<Item>();
    	items.add(item1);
    	items.add(item2);
        return items;
    }

    /**
     * @CachePut 應用到寫數據的方法上,如新增/修改方法,調用方法時會自動把相應的數據放入緩存
     * @param person
     * @return
     */
    @CachePut(value = "item" )
    @RequestMapping("/item/{id}/update")
    public Item updateItem(@PathVariable int id) {
    	Item item = new Item();
    	item.setItemId(id);
    	item.setItemName("緩存1"+id);
        return item;
    } 
   
}

小技巧:
@Cacheable可以與@CachePut配合使用,通過@Cacheable添加數據並緩存到redis中 但如果數據庫修改而再一次查詢時 緩存的數據沒有修改會出現問題 如果數據修改時使用 @CachePut 就可以在修改後同時修改redis中的數據 這樣再一次查詢時就可以保持一致了(注意要保證兩者在redis中緩存的鍵一致 這樣改的纔是同一個數據)
**

本人只是爲了記錄自己的經歷,如果侵犯到您的權益 ,請與[email protected]聯繫

**

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章