达梦数据库方言的upsert

This commit is contained in:
吴博 2024-02-22 09:51:06 +08:00
parent 011cd5458e
commit d9cda15078
3 changed files with 100 additions and 10 deletions

View File

@ -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语句

View File

@ -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
*/

View File

@ -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<String> 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);
}
}