diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml
index 5ec53c52b..1c1785589 100755
--- a/hutool-db/pom.xml
+++ b/hutool-db/pom.xml
@@ -178,5 +178,11 @@
0.5.0
test
+
+ com.dameng
+ DmJdbcDriver18
+ 8.1.2.141
+ test
+
diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java
index 6dfea6ae5..97224d159 100755
--- a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java
+++ b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectFactory.java
@@ -4,14 +4,7 @@ import cn.hutool.core.map.SafeConcurrentHashMap;
import cn.hutool.core.util.ClassLoaderUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
-import cn.hutool.db.dialect.impl.AnsiSqlDialect;
-import cn.hutool.db.dialect.impl.H2Dialect;
-import cn.hutool.db.dialect.impl.MysqlDialect;
-import cn.hutool.db.dialect.impl.OracleDialect;
-import cn.hutool.db.dialect.impl.PhoenixDialect;
-import cn.hutool.db.dialect.impl.PostgresqlDialect;
-import cn.hutool.db.dialect.impl.SqlServer2012Dialect;
-import cn.hutool.db.dialect.impl.Sqlite3Dialect;
+import cn.hutool.db.dialect.impl.*;
import cn.hutool.log.StaticLog;
import javax.sql.DataSource;
@@ -66,6 +59,8 @@ public class DialectFactory implements DriverNamePool {
return new SqlServer2012Dialect();
} else if (DRIVER_PHOENIX.equalsIgnoreCase(driverName)) {
return new PhoenixDialect();
+ } else if (DRIVER_DM7.equalsIgnoreCase(driverName)) {
+ return new DmDialect();
}
}
// 无法识别可支持的数据库类型默认使用ANSI方言,可兼容大部分SQL语句
diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectName.java b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectName.java
index eeeb1c7da..275723b75 100644
--- a/hutool-db/src/main/java/cn/hutool/db/dialect/DialectName.java
+++ b/hutool-db/src/main/java/cn/hutool/db/dialect/DialectName.java
@@ -9,12 +9,12 @@ import cn.hutool.core.util.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;
/**
* 是否为指定数据库方言,检查时不分区大小写
*
- * @param dialectName 方言名
+ * @param dialectName 方言名
* @return 是否时Oracle数据库
* @since 5.7.2
*/
diff --git a/hutool-db/src/main/java/cn/hutool/db/dialect/impl/DmDialect.java b/hutool-db/src/main/java/cn/hutool/db/dialect/impl/DmDialect.java
new file mode 100644
index 000000000..5239dbd41
--- /dev/null
+++ b/hutool-db/src/main/java/cn/hutool/db/dialect/impl/DmDialect.java
@@ -0,0 +1,95 @@
+package cn.hutool.db.dialect.impl;
+
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.db.Entity;
+import cn.hutool.db.Page;
+import cn.hutool.db.StatementUtil;
+import cn.hutool.db.dialect.DialectName;
+import cn.hutool.db.sql.SqlBuilder;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * 达梦数据库方言
+ *
+ * @author wb04307201
+ */
+public class DmDialect extends AnsiSqlDialect {
+ private static final long serialVersionUID = 3415348435502927423L;
+
+ public DmDialect() {
+ }
+
+ @Override
+ public String dialectName() {
+ return DialectName.DM.name();
+ }
+
+ @Override
+ protected SqlBuilder wrapPageSql(SqlBuilder find, Page page) {
+ // limit A , B 表示:A就是查询的起点位置,B就是你需要多少行。
+ return find.append(" limit ").append(page.getStartPosition()).append(" , ").append(page.getPageSize());
+ }
+
+ @Override
+ public PreparedStatement psForUpsert(Connection conn, Entity entity, String... keys) throws SQLException {
+ Assert.notEmpty(keys, "Keys must be not empty for DM MERGE SQL.");
+ SqlBuilder.validateEntity(entity);
+ final SqlBuilder builder = SqlBuilder.create(wrapper);
+ 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 + "= ?");
+ builder.addParams(value);
+ }
+ });
+
+ entity.forEach((field, value) -> {
+ if (StrUtil.isNotBlank(field) && !keyList.contains(field)) {
+ if (updatefieldsPart.length() > 0) {
+ // 非第一个参数,追加逗号
+ updatefieldsPart.append(", ");
+ }
+ updatefieldsPart.append(field + "= ?");
+ builder.addParams(value);
+ }
+ });
+
+ entity.forEach((field, value) -> {
+ if (StrUtil.isNotBlank(field)) {
+ if (insertfieldsPart.length() > 0) {
+ // 非第一个参数,追加逗号
+ insertfieldsPart.append(", ");
+ insertplaceHolder.append(", ");
+ }
+ insertfieldsPart.append((null != wrapper) ? wrapper.wrap(field) : field);
+ insertplaceHolder.append("?");
+ builder.addParams(value);
+ }
+ });
+
+ String tableName = entity.getTableName();
+ if (null != this.wrapper) {
+ tableName = this.wrapper.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(conn, builder);
+ }
+}
diff --git a/hutool-db/src/test/java/cn/hutool/db/DmTest.java b/hutool-db/src/test/java/cn/hutool/db/DmTest.java
new file mode 100644
index 000000000..8b59ac8a9
--- /dev/null
+++ b/hutool-db/src/test/java/cn/hutool/db/DmTest.java
@@ -0,0 +1,36 @@
+package cn.hutool.db;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.sql.SQLException;
+
+/**
+ * 达梦数据库单元测试
+ *
+ * @author wb04307201
+ */
+public class DmTest {
+
+ private static final String DS_GROUP_NAME = "dm";
+
+ @BeforeClass
+ public static void init() throws SQLException {
+ Db db = Db.use(DS_GROUP_NAME);
+ db.execute("CREATE TABLE test(a INTEGER, b INTEGER)");
+
+ db.insert(Entity.create("test").set("a", 1).set("b", 11));
+ db.insert(Entity.create("test").set("a", 2).set("b", 21));
+ db.insert(Entity.create("test").set("a", 3).set("b", 31));
+ db.insert(Entity.create("test").set("a", 4).set("b", 41));
+ }
+
+ @Test
+ public void upsertTest() throws SQLException {
+ Db db = Db.use(DS_GROUP_NAME);
+ db.upsert(Entity.create("test").set("a", 1).set("b", 111), "a");
+ Entity a1 = db.get("test", "a", 1);
+ Assert.assertEquals(Long.valueOf(111), a1.getLong("b"));
+ }
+}
diff --git a/hutool-db/src/test/resources/config/db.setting b/hutool-db/src/test/resources/config/db.setting
index cf91af97f..bcef23fbb 100644
--- a/hutool-db/src/test/resources/config/db.setting
+++ b/hutool-db/src/test/resources/config/db.setting
@@ -69,3 +69,11 @@ url = jdbc:sqlserver://looly.database.chinacloudapi.cn:1433;database=test;encryp
user = looly@looly
pass = 123
remarks = true
+
+# 测试用dm数据库
+[dm]
+url = jdbc:dm://127.0.0.1:30236/schema=dm8_test
+user = SYSDBA
+pass = SYSDBA001
+remarks = true
+