稽查规则
提示
系统提供“稽查规则”能力,支持通过 ATT_AUDIT_RULE 预置规则,并以 strategyKey 作为路由标识。
本文将说明如何新增规则元信息、实现 QualitySqlGenerator、接入数据库方言(ComponentRegistry / ComponentItem),以及在 rule.getConfig() 中扩展参数,帮助你快速完成稽查规则的扩展与适配。
一、概述
稽查规则用于对数据质量进行核查与约束,采用“预置规则表 + 策略标识 + SQL 生成器 + 数据库方言”的可扩展架构。
核心目标
- 通过表 ATT_AUDIT_RULE 管理规则元信息,关键字段
strategyKey用于路由具体实现。 - 以接口 QualitySqlGenerator 统一产出:规则 SQL、异常数据 SQL、有效数据分页 SQL。
- 通过工厂 ComponentRegistry 按数据源类型选择方言实现(
ComponentItem),适配多数据库。 - 支持在
rule.getConfig()中扩展规则参数,避免实体变更。
整体流程(简要)
- 在
ATT_AUDIT_RULE预置规则,设置唯一strategyKey。 - 新增并标注
@Component("strategyKey")的QualitySqlGenerator实现。 QualitySqlGenerator内调用ComponentRegistry→ 拿到对应ComponentItem(方言)。- 在方言中生成 SQL 片段/完整 SQL,执行核查并返回结果。
二、表结构(ATT_AUDIT_RULE)
表名:ATT_AUDIT_RULE
位置:QDATA_TEST Schema
该表用于配置和管理预置的稽查规则基本信息,后台会根据 strategyKey 字段路由到对应的规则实现。
| 字段名 | 类型 | 描述 |
|---|---|---|
| ID | BIGINT | 主键,自增 |
| NAME | VARCHAR2(128) | 规则名称 |
| QUALITY_DIM | CHAR(1) | 质量维度:1-完整性,2-唯一性,3-有效性,4-一致性,5-时效性 |
| TYPE | CHAR(1) | 规则类型 |
| LEVEL | CHAR(1) | 规则级别:1-字段级,2-表级 |
| DESCRIPTION | VARCHAR2(512) | 规则描述 |
| VALID_FLAG | VARCHAR2(1) | 是否有效:0-无效,1-有效 |
| DEL_FLAG | VARCHAR2(1) | 删除标志:0-未删除,1-已删除 |
| CREATE_BY | VARCHAR2(32) | 创建人 |
| CREATOR_ID | BIGINT | 创建人ID |
| CREATE_TIME | DATETIME | 创建时间 |
| UPDATE_BY | VARCHAR2(32) | 更新人 |
| UPDATER_ID | BIGINT | 更新人ID |
| UPDATE_TIME | DATETIME | 更新时间 |
| REMARK | VARCHAR2(512) | 备注 |
| CODE | VARCHAR2(32) | 规则编码 |
| USE_CASE | VARCHAR2(512) | 使用场景 |
| EXAMPLE | VARCHAR2(512) | 示例 |
| ICON_PATH | VARCHAR2(256) | 图标地址 |
| STRATEGY_KEY | VARCHAR2(256) | 策略标识,例如 NOT_NULL_ID_CHECK,后台根据它定位到具体稽查规则实现 |
关键点
STRATEGY_KEY:规则的唯一标识,必须与代码实现中@Component("xxx")保持一致。USE_CASE、EXAMPLE:用于帮助开发者或使用者理解规则适用场景及参考示例。
三、扩展规则步骤
3.1 在表中配置规则基本信息
- 向
ATT_AUDIT_RULE新增记录,必须配置唯一STRATEGY_KEY(如NOT_NULL_ID_CHECK)。 - 其他字段按需填写(
QUALITY_DIM、TYPE、LEVEL、USE_CASE、EXAMPLE等)。
3.2 实现 QualitySqlGenerator
位置:qdata-quality/src/main/java/tech/qiantong/qdata/quality/utils/quality/QualitySqlGenerator.java
接口:
public interface QualitySqlGenerator {
String generateSql(QualityRuleEntity rule);
String generateErrorSql(QualityRuleEntity rule);
String generateValidDataSql(QualityRuleEntity rule, int limit, int offset);
}实现与绑定(示例):
@Component("NOT_NULL_ID_CHECK") // 与表中 STRATEGY_KEY 一致
public class NotNullIdCheckGenerator implements QualitySqlGenerator {
// 仅示意,核心逻辑见 3.3
}3.3 通过工厂选择数据库方言并生成 SQL
在 generate* 方法中,通过 ComponentRegistry 按数据源类型选择对应的 ComponentItem(数据库方言实现),再调用具体的 SQL 生成方法。
示例:
@Override
public String generateSql(QualityRuleEntity rule) {
ComponentRegistry registry = new ComponentRegistry();
ComponentItem item = registry.getComponentItem(rule.getDaDatasourceById().getDatasourceType());
return item.generateCharacterValidationSql(rule); // 示例:字符校验
}
@Override
public String generateErrorSql(QualityRuleEntity rule) {
ComponentRegistry registry = new ComponentRegistry();
ComponentItem item = registry.getComponentItem(rule.getDaDatasourceById().getDatasourceType());
return item.generateCharacterValidationErrorSql(rule);
}
@Override
public String generateValidDataSql(QualityRuleEntity rule, int limit, int offset) {
ComponentRegistry registry = new ComponentRegistry();
ComponentItem item = registry.getComponentItem(rule.getDaDatasourceById().getDatasourceType());
return item.generateCharacterValidationValidDataSql(rule, limit, offset);
}3.4 方言注册与默认实现
位置:qdata-quality/src/main/java/tech/qiantong/qdata/quality/utils/qualityDB/ComponentRegistry.java
public class ComponentRegistry {
private final Map<String, ComponentItem> componentItemMap = new HashMap<>();
private final ComponentItem defaultImpl = new DefaultQuality();
public ComponentRegistry() {
this.componentItemMap.put(DbType.MYSQL.getDb(), new MySqlQuality());
this.componentItemMap.put(DbType.DM8.getDb(), new DM8Quality());
}
public ComponentItem getComponentItem(String dbCode) {
return componentItemMap.getOrDefault(dbCode, defaultImpl);
}
}说明:
内置支持的数据库类型:
MySQL→MySqlQualityDM8→DM8Quality
其他数据库类型扩展步骤:
新建实现类,实现
ComponentItem接口。在
ComponentRegistry构造函数中注册:this.componentItemMap.put(DbType.ORACLE.getDb(), new OracleQuality());
如果未匹配到具体数据库类型,将使用
DefaultQuality默认实现。
四、SQL 编写规范
4.1 SQL 片段接口
位置:qdata-quality/src/main/java/tech/qiantong/qdata/quality/utils/qualityDB/ComponentItem.java
public interface ComponentItem extends QualityFragSql {
// 通用分页
default String addPagination(String sql, int limit, int offset) {
return String.format("%s LIMIT %d OFFSET %d", sql, limit, offset);
}
}- 公共逻辑(如分页)可放在
default方法中。 - 各数据库差异化 SQL 由不同实现类完成。
4.2 数据库差异化实现
当数据库类型在现有工厂中没有满足需求时,需要自行实现。
参考 MySqlQuality:
package tech.qiantong.qdata.quality.utils.qualityDB.dialect;
import tech.qiantong.qdata.quality.dal.dataobject.quality.QualityRuleEntity;
import tech.qiantong.qdata.quality.utils.qualityDB.ComponentItem;
public class MySqlQuality implements ComponentItem {
@Override
public String fragCharacter(QualityRuleEntity rule) {
String column = rule.getRuleColumn();
String regex = (String) rule.getConfig().get("regex");
return String.format("BINARY %s REGEXP '%s'", column, regex);
}
}说明:
fragCharacter方法实现了字符校验规则的 SQL 片段。- 不同数据库(如 Oracle、PostgreSQL、Kingbase、DM8)需要各自实现适配逻辑。
五、注意事项
参数扩展
- 如果稽查规则需要新增参数,请统一存放在
rule.getConfig()中获取。 - 避免频繁修改实体类字段,提升扩展性。
- 如果稽查规则需要新增参数,请统一存放在
数据库类型扩展
- 不同数据库的 SQL 差异较大,需要在
ComponentItem的实现类中定制。 - 数据库类型扩展方式可参考 《数据连接-开发文档》 的数据库方言实现规范,保持一致性。
- 不同数据库的 SQL 差异较大,需要在
