一开始,没去查资料,后面要被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,先将所有在这天的鸟类识别结果查出,把对应的分组放在程序中,有效减少数据库连接