217 lines
6.5 KiB
Markdown
217 lines
6.5 KiB
Markdown
|
|
# 中介黑名单联合查询功能重构实现总结
|
|||
|
|
|
|||
|
|
## 一、问题描述
|
|||
|
|
|
|||
|
|
原始的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
|