diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml
index 95d236496..4f245e097 100755
--- a/hutool-db/pom.xml
+++ b/hutool-db/pom.xml
@@ -141,6 +141,12 @@
2.2.224
test
+
+ com.dameng
+ DmJdbcDriver18
+ 8.1.3.62
+ test
+
org.slf4j
slf4j-simple
diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java
index 84b0392d8..1dde6a074 100644
--- a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java
+++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectFactory.java
@@ -72,6 +72,8 @@ public class DialectFactory implements DriverNamePool {
return new SqlServer2012Dialect(dbConfig);
} else if (DRIVER_PHOENIX.equalsIgnoreCase(driverName)) {
return new PhoenixDialect(dbConfig);
+ } else if (DRIVER_DM.equalsIgnoreCase(driverName)) {
+ return new DmDialect(dbConfig);
}
}
// 无法识别可支持的数据库类型默认使用ANSI方言,可兼容大部分SQL语句
diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectName.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectName.java
index 0bdfc0756..a42039568 100644
--- a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectName.java
+++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DialectName.java
@@ -21,7 +21,7 @@ import org.dromara.hutool.core.text.StrUtil;
* @author Looly
*/
public enum DialectName {
- ANSI, MYSQL, ORACLE, POSTGRESQL, SQLITE3, H2, SQLSERVER, SQLSERVER2012, PHOENIX;
+ ANSI, MYSQL, ORACLE, POSTGRESQL, SQLITE3, H2, SQLSERVER, SQLSERVER2012, PHOENIX, DM;
/**
* 是否为指定数据库方言,检查时不分区大小写
diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DriverNamePool.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DriverNamePool.java
index 3ea8a1e8f..5d6307746 100644
--- a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DriverNamePool.java
+++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/DriverNamePool.java
@@ -73,9 +73,9 @@ public interface DriverNamePool {
*/
String DRIVER_HSQLDB = "org.hsqldb.jdbc.JDBCDriver";
/**
- * JDBC 驱动 达梦7
+ * JDBC 驱动 达梦
*/
- String DRIVER_DM7 = "dm.jdbc.driver.DmDriver";
+ String DRIVER_DM = "dm.jdbc.driver.DmDriver";
/**
* JDBC 驱动 人大金仓
*/
diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/DmDialect.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/DmDialect.java
new file mode 100644
index 000000000..5428f7714
--- /dev/null
+++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/DmDialect.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2024. looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * https://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.db.dialect.impl;
+
+import org.dromara.hutool.core.lang.Assert;
+import org.dromara.hutool.core.text.StrUtil;
+import org.dromara.hutool.db.Entity;
+import org.dromara.hutool.db.config.DbConfig;
+import org.dromara.hutool.db.dialect.DialectName;
+import org.dromara.hutool.db.sql.QuoteWrapper;
+import org.dromara.hutool.db.sql.SqlBuilder;
+import org.dromara.hutool.db.sql.StatementUtil;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 达梦数据库方言
+ *
+ * @author wb04307201
+ */
+public class DmDialect extends AnsiSqlDialect {
+ private static final long serialVersionUID = 3415348435502927423L;
+
+ /**
+ * 构造
+ *
+ * @param dbConfig 数据库配置
+ */
+ public DmDialect(final DbConfig dbConfig) {
+ super(dbConfig);
+ quoteWrapper = new QuoteWrapper('\'');
+ }
+
+ @Override
+ public String dialectName() {
+ return DialectName.DM.name();
+ }
+
+ @Override
+ public PreparedStatement psForUpsert(final Connection conn, final Entity entity, final String... keys) {
+ Assert.notEmpty(keys, "Keys must be not empty for DM MERGE SQL.");
+ SqlBuilder.validateEntity(entity);
+ final SqlBuilder builder = SqlBuilder.of(quoteWrapper);
+ final List keyList = Arrays.asList(keys);
+
+ final StringBuilder keyFieldsPart = new StringBuilder();
+ final StringBuilder updateFieldsPart = new StringBuilder();
+ final StringBuilder insertFieldsPart = new StringBuilder();
+ final StringBuilder insertPlaceHolder = new StringBuilder();
+
+ // 构建字段部分和参数占位符部分
+ entity.forEach((field, value) -> {
+ if (StrUtil.isNotBlank(field) && keyList.contains(field)) {
+ if (keyFieldsPart.length() > 0) {
+ keyFieldsPart.append(" and ");
+ }
+ keyFieldsPart.append(field).append("= ?");
+ builder.addParams(value);
+ }
+ });
+
+ entity.forEach((field, value) -> {
+ if (StrUtil.isNotBlank(field) && !keyList.contains(field)) {
+ if (updateFieldsPart.length() > 0) {
+ // 非第一个参数,追加逗号
+ updateFieldsPart.append(", ");
+ }
+ updateFieldsPart.append(field).append("= ?");
+ builder.addParams(value);
+ }
+ });
+
+ entity.forEach((field, value) -> {
+ if (StrUtil.isNotBlank(field)) {
+ if (insertFieldsPart.length() > 0) {
+ // 非第一个参数,追加逗号
+ insertFieldsPart.append(", ");
+ insertPlaceHolder.append(", ");
+ }
+ insertFieldsPart.append((null != quoteWrapper) ? quoteWrapper.wrap(field) : field);
+ insertPlaceHolder.append("?");
+ builder.addParams(value);
+ }
+ });
+
+ String tableName = entity.getTableName();
+ if (null != this.quoteWrapper) {
+ tableName = this.quoteWrapper.wrap(tableName);
+ }
+
+ builder.append("MERGE INTO ").append(tableName).append(" USING DUAL ON ").append(keyFieldsPart).append(" WHEN MATCHED THEN UPDATE SET ").append(updateFieldsPart).append(" WHEN NOT MATCHED THEN INSERT (").append(insertFieldsPart).append(") VALUES (").append(insertPlaceHolder).append(")");
+
+ return StatementUtil.prepareStatement(false, dbConfig, conn, builder.build(), builder.getParamValueArray());
+ }
+}
diff --git a/hutool-db/src/test/java/org/dromara/hutool/db/DmTest.java b/hutool-db/src/test/java/org/dromara/hutool/db/DmTest.java
new file mode 100644
index 000000000..1a1c2c7da
--- /dev/null
+++ b/hutool-db/src/test/java/org/dromara/hutool/db/DmTest.java
@@ -0,0 +1,37 @@
+package org.dromara.hutool.db;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+/**
+ * 达梦数据库单元测试
+ *
+ * @author wb04307201
+ */
+public class DmTest {
+
+ private static final String DS_GROUP_NAME = "dm";
+
+ @BeforeAll
+ @Disabled
+ public static void init() {
+ final Db db = Db.of(DS_GROUP_NAME);
+ db.execute("CREATE TABLE test(a INTEGER, b INTEGER)");
+
+ db.insert(Entity.of("test").set("a", 1).set("b", 11));
+ db.insert(Entity.of("test").set("a", 2).set("b", 21));
+ db.insert(Entity.of("test").set("a", 3).set("b", 31));
+ db.insert(Entity.of("test").set("a", 4).set("b", 41));
+ }
+
+ @Test
+ @Disabled
+ public void upsertTest() {
+ final Db db = Db.of(DS_GROUP_NAME);
+ db.upsert(Entity.of("test").set("a", 1).set("b", 111), "a");
+ final Entity a1 = db.get("test", "a", 1);
+ Assertions.assertEquals(Long.valueOf(111), a1.getLong("b"));
+ }
+}