您好,登錄后才能下訂單哦!
springboot中怎么使用redis對單個對象進(jìn)行自動緩存更新刪除,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
創(chuàng)建一個實體類
@Data @EqualsAndHashCode(callSuper = true) @Accessors(chain = true) @ApiModel(value="ERepository對象", description="題庫") public class ERepository extends BasicModel<ERepository> implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty(value = "安全分類id") private Long safeTypeId; @ApiModelProperty(value = "題型") private Integer quesType; @ApiModelProperty(value = "題干") private String quesContent; @ApiModelProperty(value = "選項") private String options; @ApiModelProperty(value = "答案") private String answer; @ApiModelProperty(value = "是否審核(0:未審核,1:已審核)") // @TableField("is_check") private Boolean isCheck; @Override protected Serializable pkVal() { return this.id; } }
創(chuàng)建一個控制器
@RequiredArgsConstructor @RestController @Slf4j @Api(tags = "題庫模塊") @RequestMapping("/api/eRepository") public class ERepositoryController { private final IERepositoryService eRepositoryService; @ApiOperation("查詢所有題目") @GetMapping(value = "/all") @ResponseBody public Result<List<ERepository>> getRespository(ERepositoryQueryCriteria criteria){ return Result.success(eRepositoryService.getRepositoryAll(criteria)); } @ApiOperation(value = "多條件查詢題目",notes = "根據(jù)各種條件查詢,可分頁 \n author:LiFang 2021/7/25") @GetMapping @ResponseBody public Result<IPage<ERepositoryDTO>> getRespository(PageVO pageVO,ERepositoryQueryCriteria criteria){ return Result.success(eRepositoryService.getRepository(pageVO.buildPage(),criteria)); } @ApiOperation(value = "按安全分類id查詢") @GetMapping(value = "/getBySafeTypeId") public Result<List<ERepository>> getRespositoryBySafeTypeId(Long id){ Long start = System.currentTimeMillis(); List<ERepository> list = eRepositoryService.getBySafeTypeId(id); Long end = System.currentTimeMillis(); System.out.println("耗時:"+(end-start)); return Result.success(list); } @ApiOperation("新增題目") @PostMapping public Result<Void> add(@RequestBody ERepository eRepository){ eRepository.setDeleted(false); eRepositoryService.addRepository(eRepository); return Result.success(); } @ApiOperation("修改題目") @PutMapping public Result<Object> update(@RequestBody ERepository eRepository){ eRepository.setDeleted(false); log.info(StrUtil.format("【修改題目 /api/eRepository】操作人id:{},被修改題目id:{}", SecurityUtils.getCurrentUserId(), eRepository.getId())); return Result.success(eRepositoryService.updateRepository(eRepository)); } @ApiOperation("刪除題目") @DeleteMapping public Result<Void> delete(@RequestBody Set<Long> ids){ eRepositoryService.deleteById(ids); return Result.success(); } }
建個service
public interface IERepositoryService extends IBasicService<ERepository> { List<ERepository> getRepositoryAll(ERepositoryQueryCriteria criteria); IPage<ERepositoryDTO> getRepository(IPage<ERepository> page,ERepositoryQueryCriteria criteria); List<ERepository> addRepository(ERepository eRepository); List<ERepository> updateRepository(ERepository eRepository); void deleteById(Set<Long> id); List<ERepository> getBySafeTypeId(Long id); }
新建service實現(xiàn)類
使用注解進(jìn)行自動緩存、更新、刪除主要是在service的實現(xiàn)類里寫
@Slf4j @Service @EnableCaching @RequiredArgsConstructor @CacheConfig(cacheNames = "repository") public class ERepositoryServiceImpl extends BasicServiceImpl<ERepositoryMapper, ERepository> implements IERepositoryService { private final ERepositoryMapper eRepositoryMapper; private final ERepositoryStruct eRepositoryStruct; // private final ERepositoryServiceImpl eRepositoryService; private final RedisUtils redisUtils; @Override public List<ERepository> getRepositoryAll(ERepositoryQueryCriteria criteria) { List<ERepository> eRepositories = eRepositoryMapper.selectList(buildERepositoryCriteria(criteria)); return eRepositories; } @Override public IPage<ERepositoryDTO> getRepository(IPage<ERepository> page,ERepositoryQueryCriteria criteria) { IPage<ERepository> eRepositoryPage = eRepositoryMapper.selectPage(page,buildERepositoryCriteria(criteria)); List<ERepositoryDTO> eRepositoryDTOList = eRepositoryStruct.toDto(eRepositoryPage.getRecords()); return PageUtil.toMapStructPage(eRepositoryPage,eRepositoryDTOList); } @Cacheable(key = "'safeTypeId:' + #p0") @Override public List<ERepository> getBySafeTypeId(Long id) { List<ERepository> eRepositoryList = eRepositoryMapper.getBySafeTypeId(id); return eRepositoryList; } private LambdaQueryWrapper<ERepository> buildERepositoryCriteria(ERepositoryQueryCriteria criteria){ LambdaQueryWrapper<ERepository> wrapper = new LambdaQueryWrapper<>(); // wrapper.eq(ERepository::getDeleted,false); if (ObjectUtil.isNotNull(criteria.getId())) { wrapper.eq(ERepository::getId,criteria.getId()); } if(StrUtil.isNotBlank(criteria.getQuesContent())){ //默認(rèn)使用like匹配 wrapper.like(ERepository::getQuesContent, criteria.getQuesContent()); } if (ObjectUtil.isNotNull(criteria.getSafeTypeId())) { wrapper.eq(ERepository::getSafeTypeId, criteria.getSafeTypeId()); } if(ObjectUtil.isNotNull(criteria.getQuesType())){ wrapper.eq(ERepository::getQuesType,criteria.getQuesType()); } if (ObjectUtil.isNotNull(criteria.getStartTime()) && ObjectUtil.isNotNull(criteria.getEndTime())) { wrapper.between(ERepository::getCreateTime , criteria.getStartTime(), criteria.getEndTime()); } return wrapper; } @CachePut(key = "'safeTypeId:' + #p0.safeTypeId") @Override public List<ERepository> addRepository(ERepository eRepository) { eRepositoryMapper.insert(eRepository); List<ERepository> list = eRepositoryMapper.getBySafeTypeId(eRepository.getSafeTypeId()); // list.add(eRepository); return list; } @CachePut(key = "'safeTypeId:' + #p0.safeTypeId") @Override public List<ERepository> updateRepository(ERepository resources) { ERepository eRepository = getById(resources.getId()); if(ObjectUtil.isEmpty(eRepository)){ log.error(StrUtil.format("【修改題目失敗】操作人id:{},修改目標(biāo)ERepository為空,目標(biāo)id:{}", SecurityUtils.getCurrentUserId(), resources.getId())); throw new BadRequestException("修改失敗,當(dāng)前數(shù)據(jù)id不存在"); } eRepositoryMapper.updateById(resources); log.info(StrUtil.format("【修改題目成功】操作人id:{},修改目標(biāo)題目:{}", SecurityUtils.getCurrentUserId(), resources)); List<ERepository> list = eRepositoryMapper.getBySafeTypeId(resources.getSafeTypeId()); // list.removeIf(item -> resources.geMId().equals(item.getId())); // list.add(resources); //清理緩存 delCaches(resources.getId()); return list; } @Override public void deleteById(Set<Long> ids) { for (Long id : ids){ eRepositoryMapper.deleteById(id); //清理緩存 delCaches(id); } log.info(StrUtil.format("【刪除題目成功】操作人id:{},刪除目標(biāo)repositories:{}", SecurityUtils.getCurrentUserId(), ids.toString())); } /** * 清理緩存 * * @param id / */ private void delCaches(Long id) { Long safeTypeId = eRepositoryMapper.getSafeTypeIdById(id); //刪除屬于該安全分類的題庫緩存 redisUtils.del(CacheKey.REPOSITORY_SAFETYPEID + safeTypeId); } }
新建mapper接口
@Component public interface ERepositoryMapper extends BasicMapper<ERepository> { @Select("SELECT * FROM e_repository WHERE safe_type_id = #{safeTypeId} AND is_deleted=0") List<ERepository> getBySafeTypeId(Long safeTypeId); @Select("SELECT safe_type_id FROM e_repository WHERE id= #{id} AND is_deleted=0") Long getSafeTypeIdById(Long id); }
6.啟動項目
使用swagger測試根據(jù)安全分類id查詢題目接口,該分類題目的查詢結(jié)果成功響應(yīng),這時打開redis管理工具,可以看到題目按分類已經(jīng)被緩存到redis中了。
再次用swagger測試查詢該分類id的所有題目,可以看到IDEA控制臺并沒有sql語句打印,仍然有查詢結(jié)果成功響應(yīng)。
@CacheConfig(cacheNames = “repository”)
放在service實現(xiàn)類上,用來配置緩存名稱。
@Cacheable(key = “‘safeTypeId:' + #p0”)
放在查詢方法上,‘safeTypeId:' + #p0作為鍵,p0是該方法的第一個參數(shù)。
作用:使用這兩個注解,會使查詢方法首先會根據(jù)key從緩存中查詢,如果緩存中沒有該鍵,則從使用sql語句到數(shù)據(jù)庫中差查詢,查詢后,響應(yīng)結(jié)果,并自動將方法的返回結(jié)果放入redis緩存中,下一次,如果再查詢就直接從redis緩存中查詢。
好處:極大提升查詢效率,并減輕服務(wù)器壓力。
@CachePut(key = “‘safeTypeId:' + #p0.safeTypeId”)
通常加到添加和更新方法上
當(dāng)訪問新增題目接口時,數(shù)據(jù)庫新增題目成功,方法返回結(jié)果會存入redis中,這次再訪問查詢屬于該分類的題目接口,會發(fā)現(xiàn)該分類的題目已經(jīng)添加成功。
當(dāng)訪問更新題目接口時,數(shù)據(jù)庫更新題目成功,方法返回結(jié)果會根據(jù)key存入redis中,當(dāng)再根據(jù)該key查詢題目時,會發(fā)現(xiàn)控制臺并沒有打印sql語句,直接從redis中查詢出結(jié)果。
@CacheEvict(key = “#p0”)
用在刪除方法上,走該刪除方法,會刪除數(shù)據(jù)庫中的該條記錄,而且會刪除key為方法的第一個參數(shù)(通常為id)的redis記錄。再次查詢該條記錄,發(fā)現(xiàn)查詢不到了。
注意:上面的方法不能用來存儲集合。
關(guān)于springboot中怎么使用redis對單個對象進(jìn)行自動緩存更新刪除問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。