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 08ed75618..2575b8546 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 @@ -28,7 +28,7 @@ import java.util.Map; * * @author loolly */ -public class DialectFactory{ +public class DialectFactory { private static final Map DIALECT_POOL = new SafeConcurrentHashMap<>(); @@ -71,6 +71,8 @@ public class DialectFactory{ return new H2Dialect(dbConfig); } else if (DriverNames.DRIVER_SQLSERVER.equalsIgnoreCase(driverName)) { return new SqlServer2012Dialect(dbConfig); + } else if (DriverNames.DRIVER_SQLSERVER_OLD.equalsIgnoreCase(driverName)) { + return new SqlServer2005Dialect(dbConfig); } else if (DriverNames.DRIVER_PHOENIX.equalsIgnoreCase(driverName)) { return new PhoenixDialect(dbConfig); } else if (DriverNames.DRIVER_DM.equalsIgnoreCase(driverName)) { diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/SqlServer2005Dialect.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/SqlServer2005Dialect.java new file mode 100644 index 000000000..d6e11db1a --- /dev/null +++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/SqlServer2005Dialect.java @@ -0,0 +1,84 @@ +/* + * 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.text.StrPool; +import org.dromara.hutool.core.text.StrUtil; +import org.dromara.hutool.db.Page; +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; + +/** + * SQLServer2005-2008方言实现
+ * 参考:jdbc-plus + * + * @author niliwei, looly + */ +public class SqlServer2005Dialect extends AnsiSqlDialect { + private static final long serialVersionUID = 1L; + + private static final String DEFAULT_TABLE_ALIAS = "table_alias_"; + private static final String DEFAULT_ROWNUM_ALIAS = "rownum_"; + + @Override + public String dialectName() { + return DialectName.SQLSERVER.name(); + } + + /** + * 构造 + * + * @param dbConfig 数据库配置 + */ + public SqlServer2005Dialect(final DbConfig dbConfig) { + super(dbConfig); + //双引号和中括号适用,双引号更广泛 + quoteWrapper = new QuoteWrapper('"'); + } + + @Override + protected SqlBuilder wrapPageSql(final SqlBuilder find, final Page page) { + String querySql = find.toString(); + + String tableAlias = DEFAULT_TABLE_ALIAS; + while (querySql.contains(tableAlias)) { + tableAlias += StrPool.UNDERLINE; + } + String rownumAlias = DEFAULT_ROWNUM_ALIAS; + while (querySql.contains(rownumAlias)) { + rownumAlias += StrPool.UNDERLINE; + } + + final String orderBy = getOrderByPart(querySql); + final String distinctStr; + if (StrUtil.startWithIgnoreCase(querySql, "select distinct")) { + querySql = querySql.substring(15); + distinctStr = "DISTINCT "; + } else { + querySql = querySql.substring(6); + distinctStr = StrUtil.EMPTY; + } + + return SqlBuilder.of("WITH " + tableAlias + " AS (SELECT " + distinctStr + "TOP 100 PERCENT " + + " ROW_NUMBER() OVER (" + orderBy + ") as " + rownumAlias + ", " + + querySql + ") SELECT * FROM " + tableAlias + " WHERE " + rownumAlias + " BETWEEN " + + (page.getBeginIndex() + 1) + " AND " + page.getEndIndex() + " ORDER BY " + rownumAlias); + } + + private static String getOrderByPart(final String sql) { + final int orderByIndex = StrUtil.indexOfIgnoreCase(sql, "order by"); + return orderByIndex > -1 ? sql.substring(orderByIndex) : "ORDER BY CURRENT_TIMESTAMP"; + } +} diff --git a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/SqlServer2012Dialect.java b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/SqlServer2012Dialect.java index 41baaea9a..0d71be3f4 100644 --- a/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/SqlServer2012Dialect.java +++ b/hutool-db/src/main/java/org/dromara/hutool/db/dialect/impl/SqlServer2012Dialect.java @@ -37,6 +37,11 @@ public class SqlServer2012Dialect extends AnsiSqlDialect { quoteWrapper = new QuoteWrapper('"'); } + @Override + public String dialectName() { + return DialectName.SQLSERVER2012.name(); + } + @Override protected SqlBuilder wrapPageSql(final SqlBuilder find, final Page page) { if (!StrUtil.containsIgnoreCase(find.toString(), "order by")) { @@ -49,9 +54,4 @@ public class SqlServer2012Dialect extends AnsiSqlDialect { .append(page.getPageSize())// .append(" row only");// } - - @Override - public String dialectName() { - return DialectName.SQLSERVER2012.name(); - } }