缓存(cache,又称高速缓存)是指可以高速访问的、用于临时存储的数据存储区。
缓存一般用于在较短的时间段对相同数据频繁读取的场合,将读取频度较高的数据放入缓存,直接从缓存取数据,以提高效率。例如以下情况:
注意:
MyBatis具有一级缓存和二级缓存共两级缓存。
建议不要使用MyBatis的二级缓存,在业务层使用可控制的缓存(如:redis)代替更好。
Shiro自带缓存,也支持第三方缓存,可以通过配置使用。
Shiro缓存的特点:
配置示例:
使用starter方式实现shiro与springboot集成时,缓存配置如下:
/*
1. 在shiro的配置类中,配置shiro的缓存管理器,shiro即会自动使用缓存,这里使用的是shiro提供的基于内存的缓存。
2. 由于spring的缓存管理器的默认名称为cacheManager,为避免冲突,此处方法名不要使用cacheManager
*/
@Bean
protected CacheManager shiroCacheManager() {
return new MemoryConstrainedCacheManager();
}
详细信息请参阅 Integrating Apache Shiro into Spring-Boot Applications
org.springframework.boot
spring-boot-starter-cache
@SpringBootApplication
@EnableCaching
public class ScgcxxApplication implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/safty/login/index.html");
}
public static void main(String[] args) {
SpringApplication.run(ScgcxxApplication.class, args);
}
}
@CacheConfig是一个类级别的注解,允许共享缓存的名称、KeyGenerator、CacheManager 和CacheResolver。
该操作会被方法级别注解覆盖。
@Cacheable是一个方法级别的注解,声明方法返回值是可缓存的,将返回值存储到缓存中以便后续使用相同参数调用时不需执行实际的方法,直接从缓存中取值。
缓存数据的key值由@Cacheable的key属性指定。
key属性指定可以使用spEL(Spring EL,即Spring表达式),其中几个重要内置变量名:targetClass(当前目标对象所属类名)、methodName(当前方法名称)、#P0(第0个参数)、#p1(第1个参数)、#ename(名称为ename的参数)
@CachePut是一个方法级别的注解,用于声明方法正常执行,并在执行后更新缓存。
@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CacheEvict是一个方法级别的注解,用于声明方法正常执行,并在执行后清空指定key值的缓存或全部的缓存。
spring cache不仅支持将数据缓存,还支持将缓存数据删除。此过程经常用于从缓存中清除过期或未使用的数据。@CacheEvict可以指定删除一个key或多个key缓存数据。此外,还提供了一个额外的属性allEntries ,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。
@Service
@Transactional
@CacheConfig(cacheNames="customer")
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerDao customerDao;
//Customer应当是可序列化类
@Cacheable(key="targetClass +'.'+ methodName+'()'")
@Override
public List getAllCustomers() {
return customerDao.findAllCustomers();
}
//Customer应当是可序列化类
@Cacheable(key="targetClass +'.'+ methodName+'(' + #p0 +')'")
@Override
public PageInfo getCustomersPage(PageParam pageParam) {
return PageCreater.createPageInfo(
()->{return customerDao.findCustomersPage(pageParam);},
pageParam
);
}
//Customer应当是可序列化类
@Cacheable(key="targetClass +'.'+ methodName+'(' + #cus_id +')'")
@Override
public Customer getCustomer(Integer cus_id) {
return customerDao.findCustomerbyId(cus_id);
}
@CacheEvict(allEntries=true)
@Override
public boolean addCustomer(CustomerDto dto) {
dto.setCus_status(DataStatusEnum.未确定.getCode());
int cnt = customerDao.insertCustomer(dto);
return cnt>0;
}
@CacheEvict(allEntries=true)
@Override
public boolean updateCustomer(CustomerDto dto) {
int cnt = customerDao.updateCustomer(dto);
return cnt>0;
}
@CacheEvict(allEntries=true)
@Override
public boolean deleteCustomer(Integer... cus_ids) {
if(cus_ids==null || cus_ids.length==0) {
return false;
}
int cnt = customerDao.deleteCustomerByIds(cus_ids);
return cnt>0;
}
@CacheEvict(allEntries=true)
@Override
public boolean updateCustomersStatus(String status, Integer[] cus_ids) {
if(cus_ids==null || cus_ids.length==0) {
return false;
}
int cnt = customerDao.updateCustomerStatusByIds(status,cus_ids);
return cnt>0;
}
}
在application.yaml文件中配置缓存日志,启动运行观察日志信息。
logging:
level:
......
org.springframework.cache: trace
......
Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
redis本身是一个内存数据库,在应用中可以充当缓存,提高系统数据查询性能。
org.springframework.boot
spring-boot-starter-cache
org.springframework.boot
spring-boot-starter-data-redis
# Redis数据库索引(默认为0)
spring.redis.database=1
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
#spring.redis.password=
# 连接池最大连接数(使用负值表示没有限制)连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=100
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=2
# 连接超时时间(毫秒)
spring.redis.timeout=15000
spring.cache.type=redis
spring.cache.redis.time-to-live=6000000
同上述 使用Springboot自动配置的简易缓存
同上述 使用Springboot自动配置的简易缓存