一、前提

已经存在一个redis-sentinel集群,两个哨兵分别如下:

/home/redis-sentinel-cluster/sentinel-1.conf
port 26379

dir "/data"
sentinel monitor mymaster 172.16.1.11 16379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 5000
sentinel parallel-syncs mymaster 1
/home/redis-sentinel-cluster/sentinel-2.conf
port 26380

dir "/data"
sentinel monitor mymaster 172.16.1.11 16379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 5000
sentinel parallel-syncs mymaster 1

二、新建maven工程:redis-sentinel-demo    最终完整工程如下:

pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.redis.sentinel.demo</groupId>
<artifactId>redis-sentinel-demo</artifactId>
<version>1.0-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--以下是spring整合redis的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
</dependencies> </project>

1、application.yml

server:
port: 8083
context-path: / spring:
redis:
sentinel:
master: mymaster
nodes: 172.16.1.11:26379,172.16.1.11:26380
pool:
max-active: 8
max-idle: 8
max-wait: -1
min-idle: 0
database: 0

2、新建redis的工具类RedisUtil

package com.redis.sentinel.demo.util;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit; /**
* @author Administrator
* @date 2019/03/19
*/
public class RedisUtil { private RedisTemplate<String, Object> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//=============================common============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key,long time){
try {
if(time>0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key){
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
} /**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key){
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key){
if(key!=null&&key.length>0){
if(key.length==1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
} //============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key){
return key==null?null:redisTemplate.opsForValue().get(key);
} /**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key,Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} } /**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key,Object value,long time){
try {
if(time>0){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}else{
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 递增
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta){
if(delta<0){
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
} /**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta){
if(delta<0){
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
} //================================Hash=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key,String item){
return redisTemplate.opsForHash().get(key, item);
} /**
* 获取hashKey对应的所有值
* @param key 键
* @return 对应的多个值
*/
public Map<Object,Object> hmget(String key){
return redisTemplate.opsForHash().entries(key);
} /**
* HashSet
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String,Object> map){
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String,Object> map, long time){
try {
redisTemplate.opsForHash().putAll(key, map);
if(time>0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key,String item,Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key,String item,Object value,long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if(time>0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 删除hash表中的值
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item){
redisTemplate.opsForHash().delete(key,item);
} /**
* 判断hash表中是否有该项的值
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item){
return redisTemplate.opsForHash().hasKey(key, item);
} /**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item,double by){
return redisTemplate.opsForHash().increment(key, item, by);
} /**
* hash递减
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item,double by){
return redisTemplate.opsForHash().increment(key, item,-by);
} //============================set=============================
/**
* 根据key获取Set中的所有值
* @param key 键
* @return
*/
public Set<Object> sGet(String key){
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 根据value从一个set中查询,是否存在
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key,Object value){
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将数据放入set缓存
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object...values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 将set数据放入缓存
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key,long time,Object...values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if(time>0) expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 获取set缓存的长度
* @param key 键
* @return
*/
public long sGetSetSize(String key){
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 移除值为value的
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object ...values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================list================================= /**
* 获取list缓存的内容
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end){
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 获取list缓存的长度
* @param key 键
* @return
*/
public long lGetListSize(String key){
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
} /**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key,long index){
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 根据索引修改list中的某条数据
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index,Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
} /**
* 用于移除键中指定的元素。接受3个参数,分别是缓存的键名,计数事件,要移除的值。计数事件可以传入的有三个值,分别是-1、0、1。
-1代表从存储容器的最右边开始,删除一个与要移除的值匹配的数据;0代表删除所有与传入值匹配的数据;1代表从存储容器的最左边开始,删除一个与要移除的值匹配的数据。
* @param key 键
* @param count
* @param value 值
* @return 移除的个数
*/
public void lRemove(String key,long count,Object value) {
try {
redisTemplate.opsForList().remove(key, count, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}

3、新建RedisConfig(主要是设置实例化redisTemplate,并设置序列化,同时实例化RedisUtil)

package com.redis.sentinel.demo.config;

import com.redis.sentinel.demo.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer; /**
* @author Administrator
* @date 2019/03/19
*/
@Configuration
@EnableCaching //开启缓存,还要继承于CachingConfigurerSupport,主要是为了注解@Cacheable、@CacheEvict、@CachePut等的使用
public class RedisConfig extends CachingConfigurerSupport {
/**
* 注入 RedisConnectionFactory
*/
@Autowired
RedisConnectionFactory redisConnectionFactory; /**
* 实例化 RedisTemplate 对象
*
* @return
*/
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
} /**
* 设置数据存入 redis 的序列化方式
*
* @param redisTemplate
* @param factory
*/
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//只有设置jdk序列化,才能新类对象比如User进行存储
redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
redisTemplate.setConnectionFactory(factory);
} /**
* 实例化RedisUtil
* @param redisTemplate
* @return
*/
@Bean
public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
RedisUtil redisUtil = new RedisUtil();
redisUtil.setRedisTemplate(redisTemplate);
return redisUtil;
}
}

4、创建RedisTestController

package com.redis.sentinel.demo.controller;

import com.redis.sentinel.demo.model.User;
import com.redis.sentinel.demo.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set; /**
* @author Administrator
* @date 2019/03/19
*/
@RestController
@RequestMapping("/redis-sentinel")
public class RedisTestController {
@Autowired
private RedisUtil redisUtil;
@RequestMapping(value = "/test",method = RequestMethod.POST)
public void postTest(){
testCommon();
testHash();
testSet();
testList();
} private void testCommon(){
System.out.println("================================测试普通缓存==================");
System.out.println("普通缓存,存入 key01 值为value01 到期时间为5秒");
redisUtil.set("key01","value01",5);
System.out.println("从redis获取key01的值:"+redisUtil.get("key01"));
System.out.println("到期时间为:"+redisUtil.getExpire("key01"));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("6秒后从redis获取key01的值:"+redisUtil.get("key01"));
System.out.println("key01是否存在:"+redisUtil.hasKey("key01"));
} private void testHash(){
System.out.println("================================测试Hash缓存==================");
System.out.println("hash缓存,存入 key03 值为{\"name\":\"zhangsan\",\"sex\":\"man\"}");
Map<String,Object> map = new HashMap<>();
map.put("name","zhangsan");
map.put("sex","man");
redisUtil.hmset("key03",map);
System.out.println("key03:"+redisUtil.hget("key03","name")+" "+redisUtil.hget("key03","sex"));
redisUtil.del("key03");
} private void testSet(){
System.out.println("================================测试Set缓存==================");
System.out.println("Set缓存,将两个User放入缓存key04");
redisUtil.sSet("key04",new User("name1","man"),new User("name2","femal"));
Set<Object> users = redisUtil.sGet("key04");
for(Object o:users){
User user = (User)o;
System.out.println(o.toString());
}
System.out.println("获取Set key04的长度:"+redisUtil.sGetSetSize("key04"));
System.out.println("删除key04");
redisUtil.del("key04");
System.out.println("获取Set key04的长度:"+redisUtil.sGetSetSize("key04")); } private void testList(){
System.out.println("================================测试List缓存==================");
System.out.println("List缓存key05");
redisUtil.lSet("key05", Arrays.asList("aa","bb","cc","dd","ee","ff","gg"));
System.out.println("List缓存key06");
redisUtil.lSet("key06","11");
redisUtil.lSet("key06","22");
redisUtil.lSet("key06","33");
redisUtil.lSet("key06","44");
redisUtil.lSet("key06","55");
redisUtil.lSet("key06","66");
redisUtil.lSet("key06","77");
System.out.println("以上两种方式的缓存是有区别的,注意看下面的长度");
System.out.println("输出key05的长度:"+redisUtil.lGetListSize("key05"));
List<Object> list = redisUtil.lGet("key05",0,redisUtil.lGetListSize("key05"));
System.out.println("输出key05的所有元素");
for(Object str:list){
System.out.println(str);
}
System.out.println("输出key06的长度:"+redisUtil.lGetListSize("key06"));
List<Object> list1 = redisUtil.lGet("key06",0,redisUtil.lGetListSize("key06"));
System.out.println("输出key06的所有元素");
for(Object str:list1){
System.out.println(str);
} System.out.println("删除key06的的55");
redisUtil.lRemove("key06",1,"55");
List<Object> list2 = redisUtil.lGet("key06",0,redisUtil.lGetListSize("key06"));
System.out.println("输出key06的长度:"+redisUtil.lGetListSize("key06"));
System.out.println("输出key06的所有元素");
for(Object str:list2){
System.out.println(str);
} redisUtil.del("key06");
redisUtil.del("key05"); }
}

5、创建springboot启动类

package com.redis.sentinel.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; /**
* @author Administrator
* @date 2019/03/19
*/
@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args);
}
}

6、启动程序并用postman进行测试

================================测试普通缓存==================
普通缓存,存入 key01 值为value01 到期时间为5秒
从redis获取key01的值:value01
到期时间为:
6秒后从redis获取key01的值:null
key01是否存在:false
================================测试Hash缓存==================
hash缓存,存入 key03 值为{"name":"zhangsan","sex":"man"}
key03:zhangsan man
================================测试Set缓存==================
Set缓存,将两个User放入缓存key04
User{name='name2', sex='femal'}
User{name='name1', sex='man'}
获取Set key04的长度:
删除key04
获取Set key04的长度:
================================测试List缓存==================
List缓存key05
List缓存key06
以上两种方式的缓存是有区别的,注意看下面的长度
输出key05的长度:
输出key05的所有元素
[aa, bb, cc, dd, ee, ff, gg]
输出key06的长度:
输出key06的所有元素 删除key06的的55
输出key06的长度:
输出key06的所有元素

三、使用Cache注解

1、@Cacheable

@Cacheable是用来声明方法是可缓存的。将结果存储到缓存中以便后续使用相同参数调用时不需执行实际的方法。直接从缓存中取值。最简单的格式需要制定缓存名称。主要用于查询。

 参数  解释  示例
 value  缓存的名称,必须指定至少一个  

@Cacheable(value=”users”)
@Cacheable(value={”users1”,”users2”}
 key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@Cacheable(value = "users", key = "#name")
@Cacheable(value = "users", key = "#p0")
 condition  缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@Cacheable(value = "users",key = "#p0", condition = "#p0 != null")

2、@CachePut

如果缓存需要更新,且不干扰方法的执行,可以使用注解@CachePut。@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

 参数  解释  示例
 value  缓存的名称,必须指定至少一个  

@CachePut(value=”users”)
@CachePut(value={”users1”,”users2”}
 key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@CachePut(value = "users", key = "#name")
@CachePut(value = "users", key = "#p0")
 condition  缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@CachePut(value = "users",key = "#p0", condition = "#p0 != null")

3、@CacheEvict

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

 参数  解释  示例
 value  缓存的名称,必须指定至少一个  

@CacheEvict(value=”users”)
 key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合

@CacheEvict(value = "users", key = "#name")
@CacheEvict(value = "users", key = "#p0")
 condition  缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存

@CacheEvict(value = "users",key = "#p0", condition = "#p0 != null")
 allEntries 缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
@CacheEvict(value = "users",allEntries=true)
 beforeInvocation 缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存

@CacheEvict(value = "users",beforeInvocation=true)

4、@Caching

有时候我们可能组合多个Cache注解使用

以上四个个注解的示例程序如下:

在上面的程中新建RedisCachableController

package com.redis.sentinel.demo.controller;

import com.redis.sentinel.demo.model.User;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import java.util.HashMap;
import java.util.Map; /**
* @author Administrator
* @date 2019/03/21
*/
@RestController
@RequestMapping("/redis-sentinel-cache")
public class RedisCachableController { private Map<String, Object> userList = new HashMap<>();
/**
* 按key为user.name进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
@CachePut(value = "users", key = "#user.name")
public User addUser(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 组合多个Cache注解使用,按user.name和user.sex两个维度进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add2", method = RequestMethod.POST)
@Caching(put = {
@CachePut(value = "users", key = "#user.name"),
@CachePut(value = "users", key = "#user.sex")
})
public User addUser2(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 先从缓存查数据,如果缓存没有,则到userList里面去拿。
* @param name
* @return
*/
@RequestMapping(value = "/query", method = RequestMethod.GET)
@Cacheable(value = "users", key = "#name", condition = "#name != null")
public User queryUserByName(@RequestParam(value = "name") String name) {
System.out.println("如果缓存没有,从map里面获取");
User user = (User) userList.get(name);
return user;
} /**
* 删除数据,从缓存中删除
* @param name
*/
@RequestMapping(value = "/del", method = RequestMethod.PUT)
@CacheEvict(value = "users", key = "#name", condition = "#name != null")
public void deleteUserByName(@RequestParam(value = "name") String name) { }
}

启动程序,用postman进行测试

1)执行add方法,将信息存入缓存

2)执行query方法,查看console

3)执行del方法,删除缓存

4)执行query方法,查看console

 5、@CacheConfig

所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置,作用在类上面,可以将上面的Controller类进行改造

在上面的程中新建RedisCachableController1

package com.redis.sentinel.demo.controller;

import com.redis.sentinel.demo.model.User;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import java.util.HashMap;
import java.util.Map; /**
* @author Administrator
* @date 2019/03/21
*/
@RestController
@RequestMapping("/redis-sentinel-cache2")
@CacheConfig(cacheNames = "users")
public class RedisCachableController1 { private Map<String, Object> userList = new HashMap<>();
/**
* 按key为user.name进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
@CachePut(key = "#user.name")
public User addUser(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 组合多个Cache注解使用,按user.name和user.sex两个维度进行缓存
* @param user
* @return
*/
@RequestMapping(value = "/add2", method = RequestMethod.POST)
@Caching(put = {
@CachePut( key = "#user.name"),
@CachePut( key = "#user.sex")
})
public User addUser2(@RequestBody User user) {
userList.put(user.getName(), user);
return user;
} /**
* 先从缓存查数据,如果缓存没有,则到userList里面去拿。
* @param name
* @return
*/
@RequestMapping(value = "/query", method = RequestMethod.GET)
@Cacheable( key = "#p0", condition = "#p0 != null")
public User queryUserByName(@RequestParam(value = "name") String name) {
System.out.println("如果缓存没有,从map里面获取");
User user = (User) userList.get(name);
return user;
} /**
* 删除数据,从缓存中删除
* @param name
*/
@RequestMapping(value = "/del", method = RequestMethod.PUT)
@CacheEvict(key = "#name", condition = "#name != null")
public void deleteUserByName(@RequestParam(value = "name") String name) { }
}

SpEL表达式

Spring Cache提供了一些供我们使用的SpEL上下文数据,下表直接摘自Spring官方文档:

名称 位置 描述 示例
methodName root对象 当前被调用的方法名 root.methodName
method root对象 当前被调用的方法 root.method.name
target root对象 当前被调用的目标对象 root.target
targetClass root对象 当前被调用的目标对象类 root.targetClass
args root对象 当前被调用的方法的参数列表 root.args[0]
caches root对象 当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cache root.caches[0].name
argument name 执行上下文 当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数 user.id
result 执行上下文 方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,’cache evict’的beforeInvocation=false) result

springboot整合redis-sentinel支持Cache注解的更多相关文章

  1. springboot整合redis(注解形式)

    springboot整合redis(注解形式) 准备工作 springboot通常整合redis,采用的是RedisTemplate的形式,除了这种形式以外,还有另外一种形式去整合,即采用spring ...

  2. springboot整合redis——redisTemplate的使用

    一.概述 相关redis的概述,参见Nosql章节 redisTemplate的介绍,参考:http://blog.csdn.net/ruby_one/article/details/79141940 ...

  3. Springboot整合Redis入门完整篇,零基础入门教学教程

    记录一次简易集成Redis缓存 自定义Redisconfig配置 自定义序列化操作 加深印像 整合前提工具环境准备: 1.redis官网 https://redis.io/download 下载安装r ...

  4. Redis-基本概念、java操作redis、springboot整合redis,分布式缓存,分布式session管理等

    NoSQL的引言 Redis数据库相关指令 Redis持久化相关机制 SpringBoot操作Redis Redis分布式缓存实现 Resis中主从复制架构和哨兵机制 Redis集群搭建 Redis实 ...

  5. SpringBoot整合Redis、ApachSolr和SpringSession

    SpringBoot整合Redis.ApachSolr和SpringSession 一.简介 SpringBoot自从问世以来,以其方便的配置受到了广大开发者的青睐.它提供了各种starter简化很多 ...

  6. 九、springboot整合redis二之缓冲配置

    1.创建Cache配置类 @Configuration @EnableCaching public class RedisCacheConfig extends CachingConfigurerSu ...

  7. springBoot整合redis(作缓存)

    springBoot整合Redis 1,配置Redis配置类 package org.redislearn.configuration; import java.lang.reflect.Method ...

  8. SpringBoot整合Redis及Redis工具类撰写

            SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果.因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable). ...

  9. SpringBoot系列十:SpringBoot整合Redis

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合 Redis 2.背景 Redis 的数据库的整合在 java 里面提供的官方工具包:jed ...

  10. SpringBoot整合redis哨兵主从服务

    前提环境: 主从配置 http://www.cnblogs.com/zwcry/p/9046207.html 哨兵配置 https://www.cnblogs.com/zwcry/p/9134721. ...

随机推荐

  1. 用spring的@Scheduled实现定时任务

    先在spring的配置文件中添加扫描 在applicationContext.xml中添加  <task:annotation-driven/>,我用的是idea有提示功能 选择第一个后会 ...

  2. Excel下拉选项二级联动

    在日常工作中,难免遇到操作excel的时候,二级联动下拉选项多用于像地市区县的应用场景 1)先把要联动的内容准备好,把它放到第二个sheet页中 2)操作级联的文本 全部选中之后,Ctrl+G -- ...

  3. 初学python---排序

    1.永久性排序 sort() a = [12,45,1,25,3] a.sort() print(a)  ----[1, 3, 12, 25, 45] 2.临时排序 sorted() a = [12, ...

  4. 移动端响应式布局--你不知道的CSS3.0媒体查询,解决rem部分情况下无法适配的场景

    媒体查询作为响应式布局的方法之一,实际项目中用途也很广.但是你真的知道怎么用吗? 例如,下面匹配 iphone6/7/8 屏幕 @media screen and (max-width: 375px) ...

  5. Mysql 存储过程批量建表

    CREATE DEFINER=`root`@`%` PROCEDURE `createTables`() begin declare i int; declare suffix varchar(20) ...

  6. 定时器&改变定时器的执行频率

    static System.Threading.Timer timer; static void Main(string[] args) { Console.WriteLine("Press ...

  7. 二十三、Interpreter 解释器模式

    设计: 代码清单: Node public abstract class Node { public abstract void parse(Context context) throws Parse ...

  8. 【iOS】値の判断

    NSString str; ){ //nilの判断 //nullの判断 //長さの判断 // ...... }

  9. openstack swift 安装(单独对象存储服务)

    参考:https://docs.openstack.org/mitaka/zh_CN/install-guide-rdo/swift.html 安装YUM包 yum install centos-re ...

  10. 数据结构python编程总结

    大数据.空间限制 布隆过滤器 使用很少的空间就可以将准确率做到很高的程度(网页黑名单系统.垃圾邮件过滤系统.爬虫的网址判重系统等) 有一定的失误率 单个样本的大小不影响布隆过滤器的大小 n个输入.k个 ...