詳解如何使用SpringBoot的緩存@Cacheable
緩存介紹
Spring 從 3.1 開始就引入了對 Cache 的支持。定義了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口來統(tǒng)一不同的緩存技術。并支持使用 JCache(JSR-107)注解簡化我們的開發(fā)。
其使用方法和原理都類似于 Spring 對事務管理的支持。Spring Cache 是作用在方法上的,其核心思想是,當我們在調用一個緩存方法時會把該方法參數(shù)和返回結果作為一個鍵值對存在緩存中。
Cache 和 CacheManager 接口說明
Cache 接口包含緩存的各種操作集合,你操作緩存就是通過這個接口來操作的。
Cache 接口下 Spring 提供了各種 xxxCache 的實現(xiàn),比如:RedisCache、EhCache、ConcurrentMapCache
CacheManager 定義了創(chuàng)建、配置、獲取、管理和控制多個唯一命名的 Cache。這些 Cache 存在于 CacheManager 的上下文中。
小結:
每次調用需要緩存功能的方法時,Spring 會檢查指定參數(shù)的指定目標方法是否已經被調用過,如果有就直接從緩存中獲取方法調用后的結果,如果沒有就調用方法并緩存結果后返回給用戶。下次調用直接從緩存中獲取。
二、@Cacheable 注解使用詳細介紹
@Cacheable 這個注解,用它就是為了使用緩存的。所以我們可以先說一下緩存的使用步驟:
緩存使用步驟
1、開啟基于注解的緩存,使用 @EnableCaching 標識在 SpringBoot 的主啟動類上。
2、標注緩存注解即可
① 第一步:開啟基于注解的緩存,使用 @EnableCaching 標注在 springboot 主啟動類上
@EnableSwagger2 @EnableScheduling @EnableFeignClients(basePackages = {"src.main.biz.smallProject.client","com.codingapi.tx"}) @EnableJpaRepositories(basePackages = {"src.main.biz.smallProject.web.*.dao","src.main.newgrand.framework.common.dao" }) @EntityScan(basePackages = { "src.main.biz.smallProject.web.*.entity","src.main.newgrand.framework.common.domain"}) @EnableCaching public class StartApp { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(StartApp.class); new SpringUtil().setApplicationContext(context); } }
② 第二步:標注緩存注解
package src.main.biz.smallProject.web.cost.service.impl; import com.querydsl.core.BooleanBuilder; import com.querydsl.core.QueryResults; import com.querydsl.core.types.Projections; import com.querydsl.jpa.impl.JPAQueryFactory; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import src.main.biz.smallProject.utils.CollectionUtils; import src.main.biz.smallProject.web.construct.form.IdsForm; import src.main.biz.smallProject.web.cost.dao.BusinessScopeJPA; import src.main.biz.smallProject.web.cost.entity.BusinessScopeEntity; import src.main.biz.smallProject.web.cost.entity.QBusinessScopeEntity; import src.main.biz.smallProject.web.cost.form.BusinessScopeForm; import src.main.biz.smallProject.web.cost.form.BusinessScopeQueryForm; import src.main.biz.smallProject.web.cost.service.BusinessScopeService; import src.main.biz.smallProject.web.cost.vo.BusinessScopeVO; import src.main.newgrand.framework.common.constants.PageData; import src.main.newgrand.framework.common.exception.BusinessException; import src.main.newgrand.framework.common.service.impl.BaseServiceImpl; import src.main.newgrand.framework.common.utils.ResultRes; import java.time.LocalDateTime; import java.util.List; import static src.main.biz.smallProject.redis.CacheConstants.BUSINESS_SCOPE_CACHE; /** * @Description * @Author yql * @Date 2022-05-10 10:44:29 */ @Service public class BusinessScopeServiceImpl extends BaseServiceImpl<BusinessScopeJPA, BusinessScopeEntity, BusinessScopeVO> implements BusinessScopeService { @Autowired private JPAQueryFactory jpaQueryFactory; QBusinessScopeEntity qBusinessScopeEntity = QBusinessScopeEntity.businessScopeEntity; @Autowired private BusinessScopeService businessScopeService; @Override @Transactional(rollbackFor = BusinessException.class) @CacheEvict(cacheNames = {BUSINESS_SCOPE_CACHE}, allEntries = true) public ResultRes add(BusinessScopeForm form) { BusinessScopeEntity businessScopeEntity = new BusinessScopeEntity(); BeanUtils.copyProperties(form,businessScopeEntity); businessScopeService.save(businessScopeEntity); return ResultRes.success(); } @Override @Transactional(rollbackFor = BusinessException.class) @CacheEvict(cacheNames = {BUSINESS_SCOPE_CACHE}, allEntries = true) public ResultRes update(BusinessScopeForm form) { BusinessScopeEntity businessScopeEntity = findById(form.getPhid()); if(businessScopeEntity == null){ throw new BusinessException("數(shù)據不存在,請檢查!"); } BeanUtils.copyProperties(form,businessScopeEntity); businessScopeService.updateSelectiveById(businessScopeEntity); return ResultRes.success(); } @Override @Cacheable(cacheNames = BUSINESS_SCOPE_CACHE, key = "{ " + "#root.methodName, #form.status}", unless = "#result == null") public ResultRes<PageData> list(BusinessScopeQueryForm form) { long currPage = form.getCurrent(); long size = form.getSize(); BooleanBuilder booleanBuilder = new BooleanBuilder(); booleanBuilder.and(qBusinessScopeEntity.phDelflag.eq(0L)); if(form.getStatus() != null){ booleanBuilder.and(qBusinessScopeEntity.status.eq(form.getStatus())); } QueryResults<BusinessScopeVO> results = jpaQueryFactory .select(Projections.bean( BusinessScopeVO.class, qBusinessScopeEntity.phid, qBusinessScopeEntity.name, qBusinessScopeEntity.status)) .from(qBusinessScopeEntity) .where(booleanBuilder) .orderBy(qBusinessScopeEntity.phInsertDt.desc()) .offset((currPage - 1) * size) .limit(size).fetchResults(); PageData pageData = new PageData(results.getResults(), results.getTotal(), size, currPage); return ResultRes.success(pageData); } @Override @Transactional(rollbackFor = BusinessException.class) @CacheEvict(cacheNames = {BUSINESS_SCOPE_CACHE}, allEntries = true) public ResultRes deleteData(IdsForm form) { List<Long> ids = form.getIds(); List<BusinessScopeEntity> businessScopeEntityList = queryFactory.selectFrom(qBusinessScopeEntity) .where(qBusinessScopeEntity.phid.in(ids).and(qBusinessScopeEntity.phDelflag.eq(0L))) .fetch(); if(CollectionUtils.isEmpty(businessScopeEntityList)){ throw new BusinessException("數(shù)據不存在,請檢查!"); } queryFactory.update(qBusinessScopeEntity) .set(qBusinessScopeEntity.phDelflag, 1L) .set(qBusinessScopeEntity.phUpdateDt, LocalDateTime.now()) .where(qBusinessScopeEntity.phid.in(ids)) .execute(); return ResultRes.success(); } }
常用屬性說明
cacheNames/value :用來指定緩存組件的名字
key :緩存數(shù)據時使用的 key,可以用它來指定。默認是使用方法參數(shù)的值。(這個 key 你可以使用 spEL 表達式來編寫)
keyGenerator :key 的生成器。 key 和 keyGenerator 二選一使用
cacheManager :可以用來指定緩存管理器。從哪個緩存管理器里面獲取緩存。
condition :可以用來指定符合條件的情況下才緩存
unless :否定緩存。當 unless 指定的條件為 true ,方法的返回值就不會被緩存。當然你也可以獲取到結果進行判斷。(通過 #result 獲取方法結果)
sync :是否使用異步模式。
spEL 編寫 key
前面說過,緩存的 key 支持使用 spEL 表達式去編寫,下面總結一下使用 spEL 去編寫 key 可以用的一些元數(shù)據:
以上就是詳解如何使用SpringBoot的緩存@Cacheable的詳細內容,更多關于SpringBoot緩存@Cacheable的資料請關注腳本之家其它相關文章!
- springboot整合單機緩存ehcache的實現(xiàn)
- SpringBoot中整合Ehcache實現(xiàn)熱點數(shù)據緩存的詳細過程
- Spring中的@Cacheable緩存注解詳解
- SpringBoot?Cache?二級緩存的使用
- Spring中緩存注解@Cache的使用詳解
- SpringCache緩存處理詳解
- 詳解Springboot @Cacheable 注解(指定緩存位置)
- Spring Cache @Cacheable 緩存在部分Service中不生效的解決辦法
- Springboot使用@Cacheable注解實現(xiàn)數(shù)據緩存
- SpringBoot使用Spring?Cache高效處理緩存數(shù)據
相關文章
解決spring-boot 打成jar包后 啟動時指定參數(shù)無效的問題
這篇文章主要介紹了解決spring-boot 打成jar包后 啟動時指定參數(shù)無效的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06SpringBoot整合SpringSecurity認證與授權
在項目開發(fā)中,權限認證是很重要的,尤其是一些管理類的系統(tǒng),對于權限要求更為嚴格,本文主要介紹了SpringBoot整合SpringSecurity認證與授權,感興趣的可以了解一下2023-11-11基于SpringBoot整合SSMP案例(開啟日志與分頁查詢條件查詢功能實現(xiàn))
這篇文章主要介紹了基于SpringBoot整合SSMP案例(開啟日志與分頁查詢條件查詢功能實現(xiàn)),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋參考下吧2023-11-11在SpringBoot下讀取自定義properties配置文件的方法
這篇文章主要介紹了在SpringBoot下讀取自定義properties配置文件的方法,文中涉及到了Spring-boot中讀取config配置文件的兩種方式,需要的朋友可以參考下2017-12-12