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); + } +}