feat: add sqlServer 2005 LimitOffsetProcessor

This commit is contained in:
开源海哥 2023-07-10 14:46:47 +08:00
parent 99729bd8ba
commit d020fe26b4
2 changed files with 181 additions and 160 deletions

View File

@ -17,6 +17,7 @@ package com.mybatisflex.core.dialect;
import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.QueryOrderBy;
import com.mybatisflex.core.query.QueryTable;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.util.CollectionUtil;
@ -29,11 +30,23 @@ import static com.mybatisflex.core.constant.SqlConsts.*;
*/
public interface LimitOffsetProcessor {
/**
* 处理构建 limit offset
*
* @param dialect 数据方言
* @param sql 已经构建的 sql
* @param queryWrapper 参数内容
* @param limitRows 用户传入的 limit 参数 可能为 null
* @param limitOffset 用户传入的 offset 参数可能为 null
*/
StringBuilder process(IDialect dialect, StringBuilder sql, QueryWrapper queryWrapper, Integer limitRows, Integer limitOffset);
/**
* MySql 的处理器
* 适合 {@link DbType#MYSQL,DbType#MARIADB,DbType#H2,DbType#CLICK_HOUSE,DbType#XCloud}
*/
LimitOffsetProcessor MYSQL = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor MYSQL = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null && limitOffset != null) {
sql.append(LIMIT).append(limitOffset).append(DELIMITER).append(limitRows);
} else if (limitRows != null) {
@ -48,7 +61,7 @@ public interface LimitOffsetProcessor {
* 适合 {@link DbType#SAP_HANA,DbType#IMPALA,DbType#HIGH_GO,DbType#VERTICA,DbType#REDSHIFT}
* 适合 {@link DbType#OPENGAUSS,DbType#TDENGINE,DbType#UXDB}
*/
LimitOffsetProcessor POSTGRESQL = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor POSTGRESQL = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null && limitOffset != null) {
sql.append(LIMIT).append(limitRows).append(OFFSET).append(limitOffset);
} else if (limitRows != null) {
@ -61,7 +74,7 @@ public interface LimitOffsetProcessor {
* derby 的处理器
* 适合 {@link DbType#DERBY,DbType#ORACLE_12C,DbType#SQLSERVER ,DbType#POSTGRE_SQL}
*/
LimitOffsetProcessor DERBY = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor DERBY = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null && limitOffset != null) {
// OFFSET ** ROWS FETCH NEXT ** ROWS ONLY")
sql.append(OFFSET).append(limitOffset).append(ROWS_FETCH_NEXT).append(limitRows).append(ROWS_ONLY);
@ -75,7 +88,7 @@ public interface LimitOffsetProcessor {
* derby 的处理器
* 适合 {@link DbType#DERBY,DbType#ORACLE_12C,DbType#SQLSERVER ,DbType#POSTGRE_SQL}
*/
LimitOffsetProcessor SQLSERVER = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor SQLSERVER = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null && limitOffset != null) {
// OFFSET ** ROWS FETCH NEXT ** ROWS ONLY")
sql.append(OFFSET).append(limitOffset).append(ROWS_FETCH_NEXT).append(limitRows).append(ROWS_ONLY);
@ -94,12 +107,29 @@ public interface LimitOffsetProcessor {
/**
* SqlServer 2005 limit 处理器
*/
LimitOffsetProcessor SQLSERVER_2005 = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor SQLSERVER_2005 = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null) {
if (limitOffset == null) {
limitOffset = 0;
}
StringBuilder newSql = new StringBuilder("SELECT * FROM (SELECT TEMP_DATAS.*, ROW_NUMBER() OVER() AS RN FROM (");
String orderByString;
List<QueryOrderBy> orderBys = CPI.getOrderBys(queryWrapper);
if (orderBys == null || orderBys.isEmpty()) {
orderByString = "ORDER BY CURRENT_TIMESTAMP";
} else {
StringBuilder orderBySql = new StringBuilder(ORDER_BY);
int index = 0;
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
for (QueryOrderBy orderBy : orderBys) {
orderBySql.append(orderBy.toSql(queryTables, dialect));
if (index != orderBys.size() - 1) {
orderBySql.append(DELIMITER);
}
index++;
}
orderByString = orderBySql.toString();
}
StringBuilder newSql = new StringBuilder("SELECT * FROM (SELECT TEMP_DATAS.*, ROW_NUMBER() OVER(").append(orderByString).append(") AS RN FROM (");
newSql.append(sql).append(") AS TEMP_DATAS) WHERE RN > ").append(limitOffset).append(" AND RN <= ").append(limitRows + limitRows);
return newSql;
}
@ -112,7 +142,7 @@ public interface LimitOffsetProcessor {
* 适合 {@link DbType#INFORMIX}
* 文档 {@link <a href="https://www.ibm.com/docs/en/informix-servers/14.10?topic=clause-restricting-return-values-skip-limit-first-options">https://www.ibm.com/docs/en/informix-servers/14.10?topic=clause-restricting-return-values-skip-limit-first-options</a>}
*/
LimitOffsetProcessor INFORMIX = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor INFORMIX = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null && limitOffset != null) {
// SELECT SKIP 2 FIRST 1 * FROM
sql.insert(6, SKIP + limitOffset + FIRST + limitRows);
@ -126,7 +156,7 @@ public interface LimitOffsetProcessor {
* Firebird 的处理器
* 适合 {@link DbType#FIREBIRD}
*/
LimitOffsetProcessor FIREBIRD = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor FIREBIRD = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null && limitOffset != null) {
// ROWS 2 TO 3
sql.append(ROWS).append(limitOffset).append(TO).append(limitOffset + limitRows);
@ -140,7 +170,7 @@ public interface LimitOffsetProcessor {
* Oracle11g及以下数据库的处理器
* 适合 {@link DbType#ORACLE,DbType#DM,DbType#GAUSS}
*/
LimitOffsetProcessor ORACLE = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor ORACLE = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null) {
if (limitOffset == null) {
limitOffset = 0;
@ -157,7 +187,7 @@ public interface LimitOffsetProcessor {
* Sybase 处理器
* 适合 {@link DbType#SYBASE}
*/
LimitOffsetProcessor SYBASE = (sql, queryWrapper, limitRows, limitOffset) -> {
LimitOffsetProcessor SYBASE = (dialect, sql, queryWrapper, limitRows, limitOffset) -> {
if (limitRows != null && limitOffset != null) {
//SELECT TOP 1 START AT 3 * FROM
sql.insert(6, TOP + limitRows + START_AT + (limitOffset + 1));
@ -168,13 +198,4 @@ public interface LimitOffsetProcessor {
};
/**
* 处理构建 limit offset
*
* @param sql 已经构建的 sql
* @param queryWrapper 参数内容
* @param limitRows 用户传入的 limit 参数 可能为 null
* @param limitOffset 用户传入的 offset 参数可能为 null
*/
StringBuilder process(StringBuilder sql, QueryWrapper queryWrapper, Integer limitRows, Integer limitOffset);
}

View File

@ -1051,7 +1051,7 @@ public class CommonsDialectImpl implements IDialect {
* 构建 limit offset 的参数
*/
protected StringBuilder buildLimitOffsetSql(StringBuilder sqlBuilder, QueryWrapper queryWrapper, Integer limitRows, Integer limitOffset) {
return limitOffsetProcessor.process(sqlBuilder, queryWrapper, limitRows, limitOffset);
return limitOffsetProcessor.process(this, sqlBuilder, queryWrapper, limitRows, limitOffset);
}