springboot使用redis对单个对象进行自动缓存更新删除的实现

网友投稿 280 2022-10-07


springboot使用redis对单个对象进行自动缓存更新删除的实现

Springboot的项目搭建在此省略,pom文件依赖什么的就不说了

创建一个实体类

@Data

@EqualsAndHashCode(callSuper = true)

@Accessors(chain = true)

@ApiModel(value="ERepository对象", description="题库")

public class ERepository extends BasicModel 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;

}

}

创建一个控制器

@RequiredArgsConstructor

@RestController

@Slf4j

@Api(tags = "题库模块")

@RequestMapping("/api/eRepository")

public class ERepositoryController {

private final IERepositoryService eRepositoryService;

@ApiOperation("查询所有题目")

@GetMapping(value = "/all")

@ResponseBody

public Result> getRespository(ERepositoryQueryCriteria criteria){

return Result.success(eRepositoryService.getRepositoryAll(criteria));

}

@ApiOperation(value = "多条件查询题目",notes = "根据各种条件查询,可分页 \n author:LiFang 2021/7/25")

@GetMapping

@ResponseBody

public Result> getRespository(PageVO pageVO,ERepositoryQueryCriteria criteria){

return Result.success(eRepositoryService.getRepository(pageVO.buildPage(),criteria));

}

@ApiOperation(value = "按安全分类id查询")

@GetMapping(value = "/getBySafeTypeId")

public Result> getRespositoryBySafeTypeId(Long id){

Long start = System.currentTimeMillis();

List list = eRepositoryService.getBySafeTypeId(id);

Long end = System.currentTimeMillijLKXrvevmZs();

System.out.println("耗时:"+(end-start));

return Result.success(list);

}

@ApiOperation("新增题目")

@PostMapping

public Result add(@RequestBody ERepository eRepository){

eRepository.setDeleted(false);

eRepositoryService.addRepository(eRepository);

return Result.success();

}

@ApiOperation("修改题目")

@PutMapping

public Result 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 delete(@RequestBody Set ids){

eRepositoryService.deleteById(ids);

return Result.success();

}

}

建个service

public interface IERepositoryService extends IBasicService {

List getRepositoryAll(ERepositoryQueryCriteria criteria);

IPage getRepository(IPage page,ERepositoryQueryCriteria criteria);

List addRepository(ERepository eRepository);

List updateRepository(ERepository eRepository);

void deleteById(Set id);

List getBySafeTypeId(Long id);

}

新建service实现类

使用注解进行自动缓存、更新、删除主要是在service的实现类里写

@Slf4j

@Service

@EnableCaching

@RequiredArgsConstructor

@CacheConfig(cacheNames = "repository")

public class ERepositoryServiceImpl extends BasicServiceImpl implements IERepositoryService {

private final ERepositoryMapper eRepositoryMapper;

private final ERepositoryStruct eRepositoryStruct;

// private final ERepositoryServiceImpl eRepositoryService;

private final RedisUtils redisUtils;

@Override

public List getRepositoryAll(ERepositoryQueryCriteria criteria) {

List eRepositories = eRepositoryMapper.selectList(buildERepositoryCriteria(criteria));

return eRepositories;

}

@Override

public IPage getRepository(IPage page,ERepositoryQueryCriteria criteria) {

IPage eRepositoryPage = eRepositoryMapper.selectPage(page,buildERepositoryCriteria(criteria));

List eRepositoryDTOList = eRepositoryStruct.toDto(eRepositoryPage.getRecords());

return PageUtil.toMapStructPage(eRepositoryPage,eRepositoryDTOList);

}

@Cacheable(key = "'safeTypeId:' + #p0")

@Override

public List getBySafeTypeId(Long id) {

List eRepositoryList = eRepositoryMapper.getBySafeTypeId(id);

return eRepositoryList;

}

private LambdaQueryWrapper buildERepositoryCriteria(ERepositoryQueryCriteria criteria){

LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();

// wrapper.eq(ERepository::getDeleted,false);

if (ObjectUtil.isNotNull(criteria.getId())) {

wrapper.eq(ERepository::getId,criteria.getId());

}

if(StrUtil.isNotBlank(criteria.getQuesContent())){

//默认使用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 addRepository(ERepository eRepository) {

eRepositoryMapper.insert(eRepository);

List list = eRepositoryMapper.getBySafeTypeId(eRepository.getSafeTypeId());

// list.add(eRepository);

return list;

}

@CachePut(key = "'safeTypeId:' + #p0.safeTypeId")

@Override

public List updateRepository(ERepository resources) {

ERepository eRepository = getById(resources.getId());

if(ObjectUtil.isEmpty(eRepository)){

log.error(StrUtil.format("【修改题目失败】操作人id:{},修改目标ERepository为空,目标id:{}", SecurityUtils.getCurrentUserId(),

resources.getId()));

throw new BadRequestException("修改失败,当前数据id不存在");

}

eRepositoryMapper.updateById(resources);

log.info(StrUtil.format("【修改题目成功】操作人id:{},修改目标题目:{}", SecurityUtils.getCurrentUserId(),

resources));

List 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 ids) {

for (Long id : ids){

eRepositoryMapper.deleteById(id);

//清理缓存

delCaches(id);

}

log.info(StrUtil.format("【删除题目成功】操作人id:{},删除目标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 ihttp://s_deleted=0")

List getBySafeTypeId(Long safeTypeId);

@Select("SELECT safe_type_id FROM e_repository WHERE id= #{id} AND is_deleted=0")

Long getSafeTypeIdById(Long id);

}

6.启动项目

使用swagger测试根据安全分类id查询题目接口,该分类题目的查询结果成功响应,这时打开redis管理工具,可以看到题目按分类已经被缓存到redis中了。

再次用swhttp://agger测试查询该分类id的所有题目,可以看到IDEA控制台并没有sql语句打印,仍然有查询结果成功响应。

@CacheConfig(cacheNames = “repository”)

放在service实现类上,用来配置缓存名称。

@Cacheable(key = “‘safeTypeId:' + #p0”)

放在查询方法上,‘safeTypeId:' + #p0作为键,p0是该方法的第一个参数。

作用:使用这两个注解,会使查询方法首先会根据key从缓存中查询,如果缓存中没有该键,则从使用sql语句到数据库中差查询,查询后,响应结果,并自动将方法的返回结果放入redis缓存中,下一次,如果再查询就直接从redis缓存中查询。

好处:极大提升查询效率,并减轻服务器压力。

@CachePut(key = “‘safeTypeId:' + #p0.safeTypeId”)

通常加到添加和更新方法上

当访问新增题目接口时,数据库新增题目成功,方法返回结果会存入redis中,这次再访问查询属于该分类的题目接口,会发现该分类的题目已经添加成功。

当访问更新题目接口时,数据库更新题目成功,方法返回结果会根据key存入redis中,当再根据该key查询题目时,会发现控制台并没有打印sql语句,直接从redis中查询出结果。

@CacheEvict(key = “#p0”)

用在删除方法上,走该删除方法,会删除数据库中的该条记录,而且会删除key为方法的第一个参数(通常为id)的redis记录。再次查询该条记录,发现查询不到了。

注意:上面的方法不能用来存储集合。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:frida的环境安装(frida框架教程)
下一篇:CCNP(ISCW)实验:配置Cisco PPPoE Server和Client(PAT的转换)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~