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,先将所有在这天的鸟类识别结果查出,把对应的分组放在程序中,有效减少数据库连接

相关推荐
小兔兔吃萝卜1 小时前
Spring 创建 Bean 的 8 种主要方式
java·后端·spring
AAA修煤气灶刘哥3 小时前
面试官: SpringBoot自动配置的原理是什么?从启动到生效,一文讲透
后端·spring·面试
qq_三哥啊5 小时前
【IDEA】设置Debug调试时调试器不进入特定类(Spring框架、Mybatis框架)
spring·intellij-idea·mybatis
别惹CC5 小时前
Spring AI 进阶之路01:三步将 AI 整合进 Spring Boot
人工智能·spring boot·spring
寒士obj6 小时前
Spring事物
java·spring
IT毕设实战小研14 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
甄超锋15 小时前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
Java小白程序员18 小时前
Spring Framework:Java 开发的基石与 Spring 生态的起点
java·数据库·spring
甄超锋19 小时前
Java Maven更换国内源
java·开发语言·spring boot·spring·spring cloud·tomcat·maven
还是鼠鼠20 小时前
tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
java·spring boot·后端·spring·maven