mybatisplus 集成逻辑删除

一开始,没去查资料,后面要被AI气死了,先看它的的话

一开始,看ai的描述,我还以为,不需要改数据库,mybatis-puls自动拦截集成就可以实现逻辑删除,c,最后还是要给数据库加一个标志位。

复制代码
ALTER TABLE bird_andconfidence ADD COLUMN deleted INT DEFAULT 0;

运行向数据库插入一个字段deleted

步骤 1: 配置全局逻辑删除属性
复制代码
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted       # 指定全局逻辑删除字段名
      logic-delete-value: 1             # 逻辑已删除值
      logic-not-delete-value:0

2.逻辑删除标准为加@TableLogic

就好了,在删除时会变为修改,将deleted字段变为1

查询时,会带上条件 AND where deleted =0;

给出我今天写的接口:

复制代码
public ResponseEntity<?> selectAllBirdsInday(
        @RequestParam("date") String date) {
    log.info("查询 {} 的所有鸟类检测结果", date);

    try {
        // 手动将 String 类型的 date 参数转换为 LocalDate 类型
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate = LocalDate.parse(date, formatter);

        List<DetectionResultVO> results = birdSelectService.SelectBirdByDate(localDate);

        if (results == null || results.isEmpty()) {
            log.info("{} 没有检测到鸟类", date);
            // 返回包含提示信息的 JSON 对象,并使用 200 OK 状态码
            Map<String, String> response = Collections.singletonMap("message", "当天没有检测到鸟类");
            return ResponseEntity.ok(response); // 200 OK
        }

        log.info("查询到 {} 个鸟类检测结果", results.size());
        return ResponseEntity.ok(results); // 200 OK, 返回检测结果列表

    } catch (DateTimeParseException e) {
        log.error("日期格式转换失败", e);
        return ResponseEntity.badRequest().body("日期格式不正确,请使用 yyyy-MM-dd 格式"); // 400 Bad Request
    } catch (Exception e) {
        log.error("查询鸟类检测结果失败", e);
        return ResponseEntity.internalServerError().body("查询失败,请稍后重试"); // 500 Internal Server Error
    }
}
复制代码
public List<DetectionResultVO> SelectBirdByDate(LocalDate date) {

    try {
        // 1. 构造查询时间范围
        LocalDateTime startOfDay = date.atStartOfDay();
        LocalDateTime endOfDay = date.atTime(LocalTime.MAX);

        // 2. 使用 Mybatis-Plus 的 QueryWrapper 构建查询条件
        QueryWrapper<DetectionResult> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("creat_time", startOfDay, endOfDay);

        // 3. 查询 DetectionResult 列表
        List<DetectionResult> detectionResults = detectionResultMapper.selectList(queryWrapper);

        if (detectionResults == null || detectionResults.isEmpty()) {
            log.info("{} 没有检测到鸟类", date);
            return null; // 或者返回 Collections.emptyList();
        }

        // 1. 获取所有 detectionResults 的 ID 列表
        List<Integer> detectionResultIds = detectionResults.stream()
                .map(DetectionResult::getId)
                .collect(Collectors.toList());

        // 2. 使用 IN 语句查询 BirdAndconfidence 列表
        QueryWrapper<BirdAndconfidence> birdQueryWrapper = new QueryWrapper<>();
        birdQueryWrapper.in("detection_results_id", detectionResultIds);

        List<BirdAndconfidence> allBirdAndConfidences = birdAndconfidenceMapper.selectList(birdQueryWrapper);

        // 3. 将查询结果按照 detection_results_id 进行分组
        Map<Integer, List<BirdAndconfidence>> birdMap = allBirdAndConfidences.stream()
                .collect(Collectors.groupingBy(BirdAndconfidence::getDetectionResultsId));

        List<DetectionResultVO> detectionResultVOS = new ArrayList<>();

        // 查询相应的多个识别结果
        for (DetectionResult detectionResult : detectionResults) {
            int detectionResultsId = detectionResult.getId();

            // 4. 从分组结果中获取对应的 BirdAndconfidence 列表
            List<BirdAndconfidence> birdAndConfidences = birdMap.getOrDefault(detectionResultsId, new ArrayList<>());

            DetectionResultVO detectionResultVO = new DetectionResultVO();
            BeanUtils.copyProperties(detectionResult, detectionResultVO);
            detectionResultVO.setResults(birdAndConfidences);
            detectionResultVOS.add(detectionResultVO);
        }

        if (detectionResultVOS == null || detectionResultVOS.isEmpty()) {
            log.info("{} 没有检测到鸟类", date);
            return null; // 或者返回 Collections.emptyList();
        }

        log.info("查询到 {} 条鸟类检测结果", detectionResultVOS.size());
        return detectionResultVOS;

    } catch (Exception e) {
        log.error("查询鸟类检测结果失败", e);
        return null; // 或者抛出异常,取决于你的业务需求
    }

}

中途,ai给出了一个优化,批量查询 BirdAndconfidence 列表: 为了避免 N+1 查询问题,可以使用 IN 语句批量查询

使用 for 循环遍历 detectionResults 列表,并在循环中查询 BirdAndconfidence 列表。 这种方式会导致 N+1 查询问题,即每次循环都需要执行一次数据库查询。 如果 detectionResults 列表中的数据量很大,会导致大量的数据库查询,影响性能。

原本

优化后

使用in,先将所有在这天的鸟类识别结果查出,把对应的分组放在程序中,有效减少数据库连接

相关推荐
BUG指挥官19 小时前
Sa-Token和Spring Security对比
java·后端·spring
geminigoth19 小时前
Spring AI Alibaba 入门开发一(备份)
java·人工智能·spring
xbgRS1 天前
spring整合mybaits
java·spring·mybatis
ruleslol1 天前
静态依赖注入 VS 动态依赖查询
spring
墨雨晨曦881 天前
Spring AI总结
java·人工智能·spring
用户3126874877201 天前
Spring Boot 异常处理到底怎么玩的?从 DispatcherServlet 到全局兜底的全链路拆解
spring
不才不才不不才1 天前
Spring 源码系列(17): HandlerMapping 与 HandlerAdapter 两大体系
java·后端·spring
(轻舟已过万重山)1 天前
第40章 Spring AI 实战:企业级 AI 应用架构
人工智能·spring·架构
堕落年代2 天前
Ollama CPU 推理大提示词优化实测报告(细致化数据版)
java·后端·spring
cfm_29142 天前
基于OAuth2.0实现微服务SSO单点登录
后端·spring·微服务·架构