SpringBoot本地缓存详解SpringBoot本地缓存详解
导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
⼀、修改启动类
启动类上添加@EnableCaching注解开启缓存。
;
batis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class DemoApplication {
public static void main(String[] args){
SpringApplication.run(DemoApplication.class, args);
}
}
⼆、@Cacheable注解
1、cacheNames 和value属性
⽤于指定缓存组件的名字。将⽅法的返回结果放在哪个缓存中,数组⽅式,可指定多个缓存。写个接⼝测试⼀下,直接⽤JdbcTemplate 通过id查⼀个⽤户,在⽅法内部打印⼀句话:
import org.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
@Controller
public class MyController {
@Autowired
JdbcTemplate jdbcTemplate;
@GetMapping(value ="/getUserById")
@ResponseBody
@Cacheable(cacheNames ="userMap")
public Map<String, Object>getUserById(Integer id){
return jdbcTemplate.queryForMap("select * from user where id="+id);
}
}
运⾏项⽬,访问接⼝:
第⼀次查询,控制台:
⽽第⼆次查询会取缓存中的数据,不会进⼊⽅法内部,也就不会打印那句话了。
2、key属性
缓存数据的key,默认使⽤的是⽅法参数的值,spel编写。
⽰例:
@Cacheable(cacheNames ="userMap",key ="#hodName+#id")
3、keyGenerator属性
写⼀个⽣成策略,并放到容器中,⽤拉姆达表达式更简洁,返回key为⽅法名+参数数组。
import t.annotation.Configuration;
import java.util.Arrays;
@Configuration
public class KeyGeneratorConfig {
@Bean
public KeyGenerator keyGenerator(){
return(o, method, objects)-> Name()+ Arrays.asList(objects).toString();
}
}
修改@Cacheable注解,keyGenerator 属性赋值为组件id,keyGenerator :
@Cacheable(cacheNames ="userMap",keyGenerator ="keyGenerator")
这样⽣成的key是getUserById[1]。
4、condition属性
表⽰符合条件的才缓存,⽰例,#id取出⽅法参数id:
@Cacheable(cacheNames ="userMap",keyGenerator ="keyGenerator",condition ="#id==1")这样就只有id为1的会被缓存。展⽰如下:
5、unless属性
表⽰除开当前条件的才会缓存。⽰例:
@Cacheable(cacheNames ="userMap",keyGenerator ="keyGenerator",unless ="#id==1")这样id为1时就不会缓存。
6、sync属性
表⽰开启异步缓存模式,默认缓存是同步执⾏的,
@Cacheable(cacheNames ="userMap",keyGenerator ="keyGenerator",sync =true)
三、@CachePut注解
到此为⽌可以发现⼀个问题,就是如果数据更新了,我们使⽤了缓存的⽅法不会去查数据库,这使得查询到的数据不准确,怎么解决呢?就⽤@CachePut注解,在⽅法更新数据时使⽤即可。先执⾏⽅法,后缓存。表⽰既调⽤⽅法,⼜更新缓存数据。内部属性和@Cacheable基本⼀致。
修改测试接⼝:
troller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
@Controller
public class MyController {
@Autowired
JdbcTemplate jdbcTemplate;
@GetMapping(value ="/getUserById")
@ResponseBody
@Cacheable(cacheNames ="userMap",key ="#id")
cacheablepublic Map<String, Object>getUserById(Integer id){
return jdbcTemplate.queryForMap("select * from user where id="+id);
}
@GetMapping(value ="/updateUserById")
@ResponseBody
@CachePut(cacheNames ="userMap",key ="#id")
public Map<String, Object>updateUserById(Integer id,String name){
jdbcTemplate.update("update user set name ="+"'"+name+"'"+" where id="+id);
return jdbcTemplate.queryForMap("select * from user where id="+id);
}
}
下⾯进⾏⼀下测试:
先查询⽤户1:
更新⽤户1的名字名为Jack:
再来查询⽤户1:
发现返回了正确的结果,再看看控制台:
发现只查询了⼀次数据库,就是第⼀次查询,后⾯更新之后并没有查数据库,⽽是直接从缓存中获取到了更新后的数据,这就得益于@CachePut注解。注意两个接⼝的cacheNames 和key应该⼀样,⽽且返回参数的类型要⼀样,因为缓存的是⽅法返回值。
四、@CacheEvict注解
⽤于清除缓存,key属性指定要清除的缓存。
@GetMapping(value ="/deleteUserById")
@ResponseBody
@CacheEvict(cacheNames ="userMap",key ="#id")
public void deleteUserById(Integer id){
}
运⾏项⽬,先请求接⼝查询⽤户1,查询结果会被缓存起来,再次查询直接从缓存中取值,不访问数据库。
之后请求删除缓存接⼝删除缓存。接着⼜查询⽤户1,由于缓存被删除,这次查询会访问数据库。
1、allEntries属性
allEntries = true表⽰清除所有的缓存数据,这⾥表⽰清除"userMap"下的所有缓存。默认是false。
@CacheEvict(cacheNames ="userMap",allEntries =true)