# getExistingIdCards 方法实现文档 ## 方法概述 **位置**: `CcdiEmployeeImportServiceImpl.java` 第200-222行 **功能**: 批量查询数据库中已存在的身份证号,用于Excel导入时的重复检测 ## 方法签名 ```java /** * 批量查询数据库中已存在的身份证号 * @param excelList Excel数据列表 * @return 已存在的身份证号集合 */ private Set getExistingIdCards(List excelList) ``` ## 实现代码 ```java private Set getExistingIdCards(List excelList) { // 1. 提取所有身份证号 List idCards = excelList.stream() .map(CcdiEmployeeExcel::getIdCard) .filter(StringUtils::isNotEmpty) .collect(Collectors.toList()); // 2. 空值检查 if (idCards.isEmpty()) { return Collections.emptySet(); } // 3. 批量查询数据库 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(CcdiEmployee::getIdCard, idCards); List existingEmployees = employeeMapper.selectList(wrapper); // 4. 返回已存在的身份证号集合 return existingEmployees.stream() .map(CcdiEmployee::getIdCard) .collect(Collectors.toSet()); } ``` ## 实现特点 ### 1. 流式处理 - 使用 Java Stream API 进行数据处理 - 代码简洁、可读性强 - 符合现代Java编程风格 ### 2. 空值过滤 - 使用 `StringUtils.isNotEmpty` 过滤空字符串 - 避免无效数据查询 - 提高查询效率 ### 3. 批量查询优化 - 使用 MyBatis Plus 的 `LambdaQueryWrapper` - 使用 `in` 条件一次性查询所有数据 - 比循环单条查询效率高得多 ### 4. 返回 Set 集合 - 自动去重 - O(1) 时间复杂度的查找操作 - 便于后续的重复检测 ## 与参考方法对比 ### 参考1: getExistingEmployeeIds (员工ID查询) ```java private Set getExistingEmployeeIds(List excelList) { List employeeIds = excelList.stream() .map(CcdiEmployeeExcel::getEmployeeId) .filter(Objects::nonNull) .collect(Collectors.toList()); if (employeeIds.isEmpty()) { return Collections.emptySet(); } List existingEmployees = employeeMapper.selectBatchIds(employeeIds); return existingEmployees.stream() .map(CcdiEmployee::getEmployeeId) .collect(Collectors.toSet()); } ``` ### 参考2: getExistingPersonIds (中介人员证件号查询) ```java private Set getExistingPersonIds(List excelList) { List personIds = excelList.stream() .map(CcdiIntermediaryPersonExcel::getPersonId) .filter(StringUtils::isNotEmpty) .collect(Collectors.toList()); if (personIds.isEmpty()) { return Collections.emptySet(); } LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.in(CcdiBizIntermediary::getPersonId, personIds); List existingIntermediaries = intermediaryMapper.selectList(wrapper); return existingIntermediaries.stream() .map(CcdiBizIntermediary::getPersonId) .collect(Collectors.toSet()); } ``` ### 实现对比 | 特性 | getExistingEmployeeIds | getExistingIdCards | getExistingPersonIds | |------|----------------------|-------------------|---------------------| | 查询字段 | employeeId (Long) | idCard (String) | personId (String) | | 空值过滤 | Objects::nonNull | StringUtils::isNotEmpty | StringUtils::isNotEmpty | | 查询方式 | selectBatchIds | selectList(wrapper.in) | selectList(wrapper.in) | | 返回类型 | Set | Set | Set | **新方法实现特点**: - 与 `getExistingPersonIds` 风格完全一致 - 都处理字符串类型的ID字段 - 都使用 `StringUtils.isNotEmpty` 过滤空值 - 都使用 `LambdaQueryWrapper.in` 批量查询 ## 使用场景 此方法将在后续的身份证号重复检测功能中使用,例如: ```java // 在导入验证中调用 Set existingIdCards = getExistingIdCards(excelList); // 检查Excel中的身份证号是否已存在 for (CcdiEmployeeExcel excel : excelList) { if (existingIdCards.contains(excel.getIdCard())) { // 身份证号重复,标记为失败 failure.setErrorMessage("该身份证号已存在"); } } ``` ## 性能优势 假设导入1000条数据: **单条查询方式**: - 1000次数据库查询 - 预计耗时: 1000ms × 1000 = 1000秒(不可接受) **批量查询方式** (当前实现): - 1次数据库查询 - 使用 in 条件查询1000个ID - 预计耗时: 100ms以内 **性能提升**: 约10000倍 ## 编译验证 ```bash mvn clean compile -pl ruoyi-ccdi -am -DskipTests ``` **结果**: ✅ BUILD SUCCESS ## 代码规范检查 ✅ 符合若依框架编码规范 ✅ 使用正确的注解(@Resource) ✅ 添加了清晰的JavaDoc注释 ✅ 方法命名规范(驼峰命名) ✅ 与现有代码风格一致 ✅ 使用MyBatis Plus最佳实践 ## 后续集成 此方法已实现完成,将在以下任务中被调用: 1. **任务2**: 修改 importEmployeeAsync 方法,调用 getExistingIdCards 2. **任务3**: 在数据验证逻辑中使用查询结果 3. **任务4**: 处理重复身份证号的错误提示 ## 总结 - ✅ 方法已成功实现 - ✅ 代码编译通过 - ✅ 遵循项目编码规范 - ✅ 与参考实现风格一致 - ✅ 性能优化到位(批量查询) - ✅ 准备好用于后续集成