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

作者:杉菜酱酱子~ 时间:2023-06-30 19:14:36 

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

创建一个实体类


@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;
   }
}

创建一个控制器


@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 = "根据各种条件查询,可分页 \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实现类

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


@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())){
           //默认使用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:{},修改目标ERepository为空,目标id:{}", SecurityUtils.getCurrentUserId(),
                   resources.getId()));
           throw new BadRequestException("修改失败,当前数据id不存在");
       }
       eRepositoryMapper.updateById(resources);
       log.info(StrUtil.format("【修改题目成功】操作人id:{},修改目标题目:{}", 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:{},删除目标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测试根据安全分类id查询题目接口,该分类题目的查询结果成功响应,这时打开redis管理工具,可以看到题目按分类已经被缓存到redis中了。

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

再次用swagger测试查询该分类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记录。再次查询该条记录,发现查询不到了。
注意:上面的方法不能用来存储集合。

来源:https://blog.csdn.net/qq_45479404/article/details/119303769

标签:springboot,redis,自动,缓存,更新,删除
0
投稿

猜你喜欢

  • java制作复制文件工具代码分享

    2022-08-05 05:30:22
  • 深入分析C#中WinForm控件之Dock顺序调整的详解

    2022-08-21 18:45:57
  • C# 写入XML文档三种方法详细介绍

    2021-11-08 23:20:08
  • Spring Security+JWT简述(附源码)

    2022-10-16 11:57:51
  • java实现科学计算器的全过程与代码

    2022-04-09 07:49:52
  • C++语言io流处理基本操作教程示例

    2023-11-02 22:07:39
  • C#中SQL参数传入空值报错解决方案

    2023-12-14 14:28:59
  • Java 二分法检索算法代码实现详解

    2022-01-05 19:13:24
  • Java注解@Transactional事务类内调用不生效问题及解决办法

    2022-04-03 18:42:06
  • 教你如何使用Java多线程编程LockSupport工具类

    2022-03-10 03:21:56
  • C#实现XML与实体类之间相互转换的方法(序列化与反序列化)

    2022-05-14 03:39:32
  • 详解Java中多进程编程的实现

    2021-12-22 01:46:06
  • Java全面解析string类型的xml字符串

    2021-06-03 21:15:18
  • SpringMVC请求参数的使用总结

    2022-11-30 22:23:18
  • C#实现农历日历的方法

    2022-08-17 21:27:29
  • Spring高阶用法之自定义业务对象组件化

    2022-02-18 07:48:55
  • springBoot 打war包 程序包com.sun.istack.internal不存在的问题及解决方案

    2023-03-28 06:12:40
  • 基于hibernate框架在eclipse下的配置方法(必看篇)

    2022-11-09 20:30:26
  • Java实现图片验证码功能

    2021-12-07 12:58:55
  • IDEA JetBrains Mono字体介绍和安装教程(详解)

    2022-01-23 17:57:51
  • asp之家 软件编程 m.aspxhome.com