From 9251e202f3bb7b717db6b05c31f420d68e8bb745 Mon Sep 17 00:00:00 2001 From: lianlonggang Date: Thu, 5 Mar 2026 18:30:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(db):=20=E6=B7=BB=E5=8A=A0=E8=BE=BE?= =?UTF-8?q?=E6=A2=A6=E6=95=B0=E6=8D=AE=E5=BA=93=E5=85=B3=E9=94=AE=E5=AD=97?= =?UTF-8?q?=E8=BD=AC=E4=B9=89=E6=8B=A6=E6=88=AA=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 DmKeywordInterceptor 拦截器,自动为达梦数据库关键字添加双引号转义 - 更新 AedEquipmentManger 实体类格式化和导入语句规范 - 支持自动识别和处理达梦数据库保留关键字,避免 SQL 语法错误 - 提升数据库兼容性,确保实体字段与达梦数据库关键字冲突时正常执行 --- .../emergency/entity/AedEquipmentManger.java | 2 +- .../config/mybatis/DmKeywordInterceptor.java | 124 ++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/DmKeywordInterceptor.java diff --git a/health-emergency/health-emergency-api/src/main/java/com/renkang/emergency/entity/AedEquipmentManger.java b/health-emergency/health-emergency-api/src/main/java/com/renkang/emergency/entity/AedEquipmentManger.java index 0a0f7d7..7d68910 100644 --- a/health-emergency/health-emergency-api/src/main/java/com/renkang/emergency/entity/AedEquipmentManger.java +++ b/health-emergency/health-emergency-api/src/main/java/com/renkang/emergency/entity/AedEquipmentManger.java @@ -345,7 +345,7 @@ public class AedEquipmentManger implements Serializable { */ @Excel(name = "型号", width = 15) @Schema(title = "型号") - @TableField("modelNumber") + @TableField("MODEL_NUMBER") private String model; /** * 来源字典 设备类型 1:立式 ,2:挂式,3:车载 diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/DmKeywordInterceptor.java b/jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/DmKeywordInterceptor.java new file mode 100644 index 0000000..829ebbf --- /dev/null +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/DmKeywordInterceptor.java @@ -0,0 +1,124 @@ +package org.jeecg.config.mybatis; + +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.SystemMetaObject; +import org.springframework.stereotype.Component; + +import java.sql.Connection; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 达梦数据库关键字拦截器 + * 自动为 SQL 中的关键字别名添加双引号,避免关键字冲突 + * + * @author system + * @date 2026-03-05 + */ +@Slf4j +@Component +@Intercepts({ + @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}) +}) +public class DmKeywordInterceptor implements Interceptor { + + /** + * 达梦数据库关键字列表(常见关键字) + * 可根据实际需要添加更多关键字 + */ + private static final Set DM_KEYWORDS = new HashSet<>(Arrays.asList( + "MODEL", "BEGIN", "END" + )); + + @Override + public Object intercept(Invocation invocation) throws Throwable { + try { + StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); + MetaObject metaObject = SystemMetaObject.forObject(statementHandler); + + String sql = (String) metaObject.getValue("delegate.boundSql.sql"); + + // 处理 AS 别名关键字冲突 + String processedSql = processKeywordAlias(sql); + + // 如果 SQL 被修改,则记录日志并更新 + if (!sql.equals(processedSql)) { + log.debug("达梦关键字拦截器处理SQL - 原始: {} => 处理后: {}", sql, processedSql); + metaObject.setValue("delegate.boundSql.sql", processedSql); + } + } catch (Exception e) { + log.error("达梦关键字拦截器处理SQL异常", e); + // 发生异常时不影响正常流程,继续执行 + } + + return invocation.proceed(); + } + + /** + * 处理 SQL 中的关键字别名 + * 将关键字别名用双引号包裹 + * + * @param sql 原始 SQL + * @return 处理后的 SQL + */ + private String processKeywordAlias(String sql) { + if (sql == null || sql.trim().isEmpty()) { + return sql; + } + + // 正则匹配: 字段名 as 别名 的模式 + // 例如: model_no as model -> model_no as "model" + Pattern pattern = Pattern.compile( + "\\b([\\w.`]+)\\s+(?i:as)\\s+(\\w+)\\b", + Pattern.CASE_INSENSITIVE + ); + + Matcher matcher = pattern.matcher(sql); + StringBuffer sb = new StringBuffer(); + + while (matcher.find()) { + String alias = matcher.group(2); + // 检查别名是否为关键字,且未被引号包裹 + if (DM_KEYWORDS.contains(alias.toUpperCase()) && !alias.startsWith("\"")) { + // 给关键字别名加上双引号 + matcher.appendReplacement(sb, + matcher.group(1) + " AS \"" + alias + "\""); + } + } + matcher.appendTail(sb); + + return sb.toString(); + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + @Override + public void setProperties(Properties properties) { + // 可以通过配置文件注入额外的关键字 + } + + /** + * 添加自定义关键字到黑名单 + * + * @param keywords 关键字数组 + */ + public static void addKeywords(String... keywords) { + if (keywords != null) { + for (String keyword : keywords) { + if (keyword != null && !keyword.trim().isEmpty()) { + DM_KEYWORDS.add(keyword.toUpperCase()); + } + } + } + } +} \ No newline at end of file