From d9cda1507876ec300a6cb15a4acd187729a211d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=8D=9A?= Date: Thu, 22 Feb 2024 09:51:06 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=BE=BE=E6=A2=A6=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=96=B9=E8=A8=80=E7=9A=84upsert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/db/dialect/DialectFactory.java | 11 +-- .../cn/hutool/db/dialect/DialectName.java | 4 +- .../cn/hutool/db/dialect/impl/DmDialect.java | 95 +++++++++++++++++++ 3 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 hutool-db/src/main/java/cn/hutool/db/dialect/impl/DmDialect.java 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..8b035cbcc --- /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 wubo + */ +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); + } +} From 3c5f905195128d33760911aed7b9bb86f086ee56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=8D=9A?= Date: Thu, 22 Feb 2024 10:32:52 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=BE=BE=E6=A2=A6=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E6=96=B9=E8=A8=80=E7=9A=84upsert=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hutool-db/pom.xml | 6 ++++ .../cn/hutool/db/dialect/impl/DmDialect.java | 2 +- .../src/test/java/cn/hutool/db/DmTest.java | 36 +++++++++++++++++++ .../src/test/resources/config/db.setting | 8 +++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 hutool-db/src/test/java/cn/hutool/db/DmTest.java diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml index 74ddf44cc..50f44c10a 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/impl/DmDialect.java b/hutool-db/src/main/java/cn/hutool/db/dialect/impl/DmDialect.java index 8b035cbcc..5239dbd41 100644 --- 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 @@ -17,7 +17,7 @@ import java.util.List; /** * 达梦数据库方言 * - * @author wubo + * @author wb04307201 */ public class DmDialect extends AnsiSqlDialect { private static final long serialVersionUID = 3415348435502927423L; 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 +