五、SpringBoot缓存
一.JSR-107规范(接口)
Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
1、CachingProvider(缓存提供者)
CachingProvider定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider。
2、CacheManager(缓存管理器)
CacheManager定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
3、Cache(缓存)
Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
4、Entry(缓存记录中的一条数据)
Entry是一个存储在Cache中的key-value对。
5、Expiry(缓存的有效期)
Expiry每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置
二.Spring缓存抽象
Spring简化了JSR107的缓存接口,定义了Cache和CacheManager接口来统一不同的缓存技术。
1、CacheManager(缓存管理器)
缓存管理器,用于管理各种Cache组件
2、Cache(缓存接口)
定义缓存操作,实现有RedisCache、EhCacheCache等
3、缓存注解
1.@Cachecble
主要针对方法配置,能够根据方法的请求参数对结果进行缓存。
@Cacheable可以标记在一个方法上,也可以标记在一个类上。当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果,至于键的话,Spring又支持两种策略,默认策略和自定义策略,默认缓存策略和自定义缓存策略只会生效一个。需要注意的是当一个支持缓存的方法在对象内部被调用时是不会触发缓存功能的。@Cacheable可以指定三个属性,value、key和condition。
(1).cacheNames/value
指定缓存组件的名字
(2).key
指定缓存数据使用的key,可以手动指定,默认使用的是方法参数的值。
(3).keyGenerator
key的生成器,可以自己制定
(4).cacheManager
指定缓存管理器,或者cacheResolver指定获取缓存解析器
(5).condition
指定符合条件的情况下才进行缓存
(6).unless
只有当满足指定情况下才不进行缓存
(7).sync
是否异步缓存,异步方式不支持unless
2.@CacheEvict
清空缓存,用在删除方法上。
(1).allEntries
清除所有的缓存数据
(2).key
清楚指定key的数据
(3).beforeInvocation
默认为false,缓存的清除是否在方法之前执行。
3.@CachePut
保证方法被调用,又希望结果被缓存
使用场景就是修改了数据库的数据,同时更新缓存。先调用目标方法,再将目标方法的结果进行缓存。
注意:
CachePut如果和Cachecble联用,需要注意两个方法的key值要一致。
4.@EnableCachING
开启基于注解的缓存
5.@Caching
@Caching=@Cachecble+@CachePut+@CacheEvict
@Caching(
cacheable = {
@Cacheable(value = "DictData", key = "id")
},
put = {
@CachePut(value = "DictData", key = "id")
},
evict = {
@CacheEvict(key = "id")
}
)
public DictData selectDictDataList(Integer id) {
return dictDataMapper.selectDictDataList(id);
}
6.@CacheConfig
缓存配置文件
4、重要概念
1.KeyGenerator(缓存key生成策略)
Value为查询到的数据,Key有不同的生成策略。
2.serialize(序列化)
三.SpringBoot缓存demo
1、主启动类
@SpringBootApplication
@MapperScan("com.example.demo.mapper")//扫描的是包,不是类。
@EnableCaching//开启注解缓存
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2、Service:@Cachecble
@Cacheable(value = "DictData",key="#id")
public DictData selectDictDataList(Integer id) {
return dictDataMapper.selectDictDataList(dictData);
}
四.SpringBoot整合Redis
1、添加引用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
2、配置文件
最简单的配置是只配置redis的host地址就行
#redis配置
redis:
#数据库索引
database: 0
host: 127.0.0.1
port: 6379
password:xxx
jedis:#配置连接池
pool:
#最大连接数
max-active: 8
#最大阻塞等待时间(负数表示没限制)
max-wait: -1
#最大空闲
max-idle: 8
#最小空闲
min-idle: 0
#连接超时时间
timeout: 10000
3、使用
RedisTemplate和StringRedisTemplate要读写一致,比如使用RedisTemplate去写入,就要使用RedisTemplate去读取,否则会报错,原因是两种模板的序列化方式不同。
@Autowired
RedisTemplate redisTemplate;//操作K-V对象
@Autowired
StringRedisTemplate stringRedisTemplate;//操作String字符串
@Component
public class MessageSender {
@Autowired
public StringRedisTemplate stringRedisTemplate;
public void sendMessage(CmdMessage message){
stringRedisTemplate.convertAndSend(message.getChannel(), JSONObject.toJSONString(message));
}
}
4、SpringCache操作缓存
对于缓存声明,Spring的缓存提供了一组java注解:
@Cacheable :写入缓存
@CacheEvict:清除缓存
@CachePut:更新缓存
@Caching:组合多个缓存操作
@CacheConfig:设置类级别上共享的一些常见缓存设置
1.主启动开启SpringCache
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(CourseApplication.class );
}
}
2.写入缓存
//@Cacheable(cacheNames = "user",key = "'id1'")
@Cacheable(cacheNames = "user",key = "#id")
public User selectUserById(Long id) {
return userDao.selectUserById(id);
}
常见的用法:
@Cacheable(cacheNames = “user”,key = “‘id1’”) :固定一个key 效果如:“user:id1”
@Cacheable(cacheNames = “user”,key = “#obj.id”) :取参数obj对象的id的值作为key ,效果如:“user::1”
@Cacheable(cacheNames = “user”,key = “#id”,condition="#id > 10") : 需要满足id大于10才做缓存
3.删除缓存
在数据库做了事务操作(增删改),需要把缓存中的数据删除,等待下一次查询重新同步缓存数据,在SpringCache中可以使用 @CacheEvict 注解完成,他会主动匹配key完成缓存的剔除工作
@CacheEvict(cacheNames = "user",key = "#id")
public void deleteUserById(Long id){
userDao.deleteUserById(id);
}
4.更新缓存
更新缓存使用@CachePut注解,和@Cacheable用法相同,他会把方法的返回值自动更新到缓存,以注解的key做自动匹配。
注意:建议不要把@CachePut和@Cacheable作用于同一个方法,可能会有功能上的冲突
@CachePut(cacheNames = "user",key = "#user.id")
public User updateUserById(User user){
userDao.updateUserById(user);
return user;
}
5.组合操作
@Caching注解可以组合多个缓存操作,比如删除多个缓存
//删除多个缓存,user和其账户一起删除
@Caching(evict = { @CacheEvict(cacheNames="user", key = "#user.id"), @CacheEvict(cacheNames="account", key = "#user.id") })
public void updateUserById(User user){
userDao.updateUserById(user);
return user;
}
6.公共配置
@CacheConfig(cacheName="user")
public class CacheService{
@CacheEvict(key = "#id")
public void deleteUserById(Long id){
userDao.deleteUserById(id);
}
@CachePut(key = "#user.id")
public User updateUserById(User user){
userDao.updateUserById(user);
return user;
}
}