2023年11月26日发(作者:)

springboot使⽤redis对单个对象进⾏⾃动缓存、更新、删除

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

1. 创建⼀个实体类

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

}

}

2. 创建⼀个控制器

@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();

}

}

3. 建个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);

}

4. 新建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<>();

// (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:' + #peId")

@Override

public List<ERepository> addRepository(ERepository eRepository) {

eRepositoryMapper.insert(eRepository);

List<ERepository> list = eRepositoryMapper.getBySafeTypeId(eRepository.getSafeTypeId());

// (eRepository);

return list;

}

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

@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());

// If(item -> ().equals(()));

// (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);

}

}

5. 新建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中了。

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

1.

@CacheConfig(cacheNames = “repository”)

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

2.

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

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

作⽤:使⽤这两个注解,会使查询⽅法⾸先会根据key从缓存中查询,如果缓存中没有该键,则从使⽤sql语句到数据库中差查询,查

询后,响应结果,并⾃动将⽅法的返回结果放⼊redis缓存中,下⼀次,如果再查询就直接从redis缓存中查询。

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

3.

@CachePut(key = “‘safeTypeId:’ + #peId”)

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

当访问新增题⽬接⼝时,数据库新增题⽬成功,⽅法返回结果会存⼊redis中,这次再访问查询属于该分类的题⽬接⼝,会发现该分类

的题⽬已经添加成功。