Files
ccdi/doc/plans/2026-02-05-intermediary-blacklist-union-query-implementation.md
2026-02-05 13:33:27 +08:00

6.5 KiB
Raw Blame History

中介黑名单联合查询功能重构实现总结

一、问题描述

原始的SQL错误Unknown column 'relation_type_field' in 'field list'

根本原因:

  1. 实体类 CcdiBizIntermediary 中定义了不存在的字段 relationTypeField
  2. 实体类中的 dataSource 字段与数据库字段 date_source 映射不匹配
  3. 原有的列表查询实现通过Java层合并两张表的数据,效率较低且无法利用数据库优化

二、解决方案

2.1 修复实体类字段映射

文件: ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/CcdiBizIntermediary.java

修改内容:

  1. 删除了不存在的 relationTypeField 字段第70行
  2. dataSource 字段添加了 @TableField("date_source") 注解第70行
// 修改前
private String relationTypeField;
private String dataSource;

// 修改后
@TableField("date_source")
private String dataSource;

2.2 创建联合查询Mapper接口

新增文件: ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiIntermediaryMapper.java

功能:

  • 定义联合查询方法 selectIntermediaryList()
  • 定义统计查询方法 selectIntermediaryCount()
  • 支持按中介类型筛选:1=个人, 2=实体, null=全部

2.3 创建MyBatis XML Mapper

新增文件: ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiIntermediaryMapper.xml

SQL设计策略

  1. 单表查询模式(当指定中介类型时)

    • intermediaryType=1:仅查询 ccdi_biz_intermediary
    • intermediaryType=2:仅查询 ccdi_enterprise_base_info
  2. 联合查询模式当intermediaryType为null时

    • 使用 UNION ALL 联合两张表
    • 外层包裹 SELECT * FROM (...) AS combined_result 用于统一排序和分页
    • 按创建时间倒序排列
  3. 动态SQL特性

    • 使用 MyBatis 动态SQL实现灵活的查询条件组合
    • 支持姓名模糊查询
    • 支持证件号/统一社会信用代码精确查询
    • 支持分页LIMIT + OFFSET

查询条件映射:

查询参数 个人中介表字段 实体中介表字段
name name enterprise_name
certificateNo person_id social_credit_code
intermediaryType person_type='中介' risk_level='1' AND ent_source='INTERMEDIARY'

2.4 优化Service层实现

文件: ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java

修改内容:

  1. 注入新的 CcdiIntermediaryMapper
  2. 重写 selectIntermediaryPage() 方法使用XML联合查询
  3. 删除原有的Java层合并数据和手动分页逻辑

性能优势:

  • 数据库层面实现分页,减少内存占用
  • 利用数据库索引优化查询性能
  • 减少网络传输数据量

2.5 扩展查询DTO

文件: ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiIntermediaryQueryDTO.java

新增字段:

private Integer pageNum;   // 页码
private Integer pageSize;  // 每页大小

三、技术实现细节

3.1 分页实现

MyBatis Plus的分页机制

  • MyBatis Plus的分页从1开始page.getCurrent()
  • SQL的OFFSET从0开始
  • 需要转换:pageNum = page.getCurrent() - 1

SQL分页语法

LIMIT #{pageSize}
OFFSET #{pageNum} * #{pageSize}

3.2 UNION ALL vs UNION

  • 使用 UNION ALL:保留所有记录,包括重复记录
  • 性能优势UNION ALL 不进行去重排序,性能更好
  • 业务场景:个人中介和实体中介不会重复,无需去重

3.3 动态SQL设计

使用MyBatis的 <if> 标签实现:

<if test="intermediaryType != null and intermediaryType == '1'">
    <!-- 个人中介查询 -->
</if>
<if test="intermediaryType != null and intermediaryType == '2'">
    <!-- 实体中介查询 -->
</if>
<if test="intermediaryType == null or intermediaryType == ''">
    <!-- 联合查询 -->
</if>

四、测试脚本

文件: doc/test/scripts/test_union_query.sh

测试用例:

  1. Test 1: 查询全部中介UNION查询
  2. Test 2: 仅查询个人中介(单表查询)
  3. Test 3: 仅查询实体中介(单表查询)
  4. Test 4: 按姓名模糊查询
  5. Test 5: 按证件号精确查询
  6. Test 6: 分页功能测试
  7. Test 7: 组合查询测试(类型+姓名+分页)

五、文件清单

修改的文件

  1. ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/CcdiBizIntermediary.java - 删除冗余字段,修复字段映射
  2. ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java - 重构查询逻辑
  3. ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/domain/dto/CcdiIntermediaryQueryDTO.java - 添加分页参数

新增的文件

  1. ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiIntermediaryMapper.java - 联合查询Mapper接口
  2. ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiIntermediaryMapper.xml - MyBatis XML Mapper
  3. doc/test/scripts/test_union_query.sh - 测试脚本

删除的文件

  1. ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiIntermediaryMapper.xml - 旧的错误配置

六、优势总结

6.1 性能提升

  • 数据库层面分页:避免加载全部数据到内存
  • 索引优化:充分利用数据库索引
  • 减少网络传输:只传输需要的数据

6.2 代码质量

  • 职责分离查询逻辑集中在Mapper层
  • 代码简洁删除复杂的Java层合并逻辑
  • 易于维护SQL集中管理便于优化

6.3 灵活性

  • 动态查询:支持单表和联合查询灵活切换
  • 条件组合:支持多种查询条件组合
  • 易于扩展后续新增字段或查询条件只需修改XML

七、后续建议

  1. 索引优化

    • ccdi_biz_intermediary: 确保字段有合适索引
    • ccdi_enterprise_base_info: 确保 risk_levelent_source 有索引
  2. 性能监控

    • 监控慢查询日志
    • 根据实际数据量调整分页大小
  3. 功能扩展

    • 考虑添加更多排序字段选项
    • 考虑支持批量导出时的流式查询

八、执行测试

# Windows环境
cd doc\test\scripts
bash test_union_query.sh

# Linux/Mac环境
cd doc/test/scripts
chmod +x test_union_query.sh
./test_union_query.sh

九、回滚方案

如果新实现出现问题可以通过Git回滚到之前的版本

git checkout HEAD~1 -- ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java

删除新增的Mapper文件即可恢复原状。


实现日期: 2026-02-05 实现人: Claude Code 版本: v2.0