Files
ccdi/doc/plans/2026-02-05-intermediary-blacklist-union-query-implementation.md

217 lines
6.5 KiB
Markdown
Raw Normal View History

2026-02-05 13:33:27 +08:00
# 中介黑名单联合查询功能重构实现总结
## 一、问题描述
原始的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行
```java
// 修改前
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`
**新增字段:**
```java
private Integer pageNum; // 页码
private Integer pageSize; // 每页大小
```
## 三、技术实现细节
### 3.1 分页实现
**MyBatis Plus的分页机制**
- MyBatis Plus的分页从1开始`page.getCurrent()`
- SQL的OFFSET从0开始
- 需要转换:`pageNum = page.getCurrent() - 1`
**SQL分页语法**
```sql
LIMIT #{pageSize}
OFFSET #{pageNum} * #{pageSize}
```
### 3.2 UNION ALL vs UNION
- **使用 UNION ALL**:保留所有记录,包括重复记录
- **性能优势**UNION ALL 不进行去重排序,性能更好
- **业务场景**:个人中介和实体中介不会重复,无需去重
### 3.3 动态SQL设计
使用MyBatis的 `<if>` 标签实现:
```xml
<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_level``ent_source` 有索引
2. **性能监控**
- 监控慢查询日志
- 根据实际数据量调整分页大小
3. **功能扩展**
- 考虑添加更多排序字段选项
- 考虑支持批量导出时的流式查询
## 八、执行测试
```bash
# 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回滚到之前的版本
```bash
git checkout HEAD~1 -- ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java
```
删除新增的Mapper文件即可恢复原状。
---
**实现日期:** 2026-02-05
**实现人:** Claude Code
**版本:** v2.0