Files
ccdi/doc/test-data/employee/getExistingIdCards实现文档.md

5.5 KiB
Raw Blame History

getExistingIdCards 方法实现文档

方法概述

位置: CcdiEmployeeImportServiceImpl.java 第200-222行

功能: 批量查询数据库中已存在的身份证号用于Excel导入时的重复检测

方法签名

/**
 * 批量查询数据库中已存在的身份证号
 * @param excelList Excel数据列表
 * @return 已存在的身份证号集合
 */
private Set<String> getExistingIdCards(List<CcdiEmployeeExcel> excelList)

实现代码

private Set<String> getExistingIdCards(List<CcdiEmployeeExcel> excelList) {
    // 1. 提取所有身份证号
    List<String> idCards = excelList.stream()
            .map(CcdiEmployeeExcel::getIdCard)
            .filter(StringUtils::isNotEmpty)
            .collect(Collectors.toList());

    // 2. 空值检查
    if (idCards.isEmpty()) {
        return Collections.emptySet();
    }

    // 3. 批量查询数据库
    LambdaQueryWrapper<CcdiEmployee> wrapper = new LambdaQueryWrapper<>();
    wrapper.in(CcdiEmployee::getIdCard, idCards);
    List<CcdiEmployee> 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查询)

private Set<Long> getExistingEmployeeIds(List<CcdiEmployeeExcel> excelList) {
    List<Long> employeeIds = excelList.stream()
            .map(CcdiEmployeeExcel::getEmployeeId)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());

    if (employeeIds.isEmpty()) {
        return Collections.emptySet();
    }

    List<CcdiEmployee> existingEmployees = employeeMapper.selectBatchIds(employeeIds);
    return existingEmployees.stream()
            .map(CcdiEmployee::getEmployeeId)
            .collect(Collectors.toSet());
}

参考2: getExistingPersonIds (中介人员证件号查询)

private Set<String> getExistingPersonIds(List<CcdiIntermediaryPersonExcel> excelList) {
    List<String> personIds = excelList.stream()
            .map(CcdiIntermediaryPersonExcel::getPersonId)
            .filter(StringUtils::isNotEmpty)
            .collect(Collectors.toList());

    if (personIds.isEmpty()) {
        return Collections.emptySet();
    }

    LambdaQueryWrapper<CcdiBizIntermediary> wrapper = new LambdaQueryWrapper<>();
    wrapper.in(CcdiBizIntermediary::getPersonId, personIds);
    List<CcdiBizIntermediary> 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 批量查询

使用场景

此方法将在后续的身份证号重复检测功能中使用,例如:

// 在导入验证中调用
Set<String> 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倍

编译验证

mvn clean compile -pl ruoyi-ccdi -am -DskipTests

结果: BUILD SUCCESS

代码规范检查

符合若依框架编码规范 使用正确的注解(@Resource 添加了清晰的JavaDoc注释 方法命名规范(驼峰命名) 与现有代码风格一致 使用MyBatis Plus最佳实践

后续集成

此方法已实现完成,将在以下任务中被调用:

  1. 任务2: 修改 importEmployeeAsync 方法,调用 getExistingIdCards
  2. 任务3: 在数据验证逻辑中使用查询结果
  3. 任务4: 处理重复身份证号的错误提示

总结

  • 方法已成功实现
  • 代码编译通过
  • 遵循项目编码规范
  • 与参考实现风格一致
  • 性能优化到位(批量查询)
  • 准备好用于后续集成