瀏覽代碼

SQLServer2005分页优化.

nieqiurong 1 年之前
父節點
當前提交
d5abb8deeb

+ 8 - 10
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/pagination/dialects/SQLServer2005Dialect.java

@@ -30,7 +30,9 @@ import java.util.regex.Pattern;
  */
 public class SQLServer2005Dialect implements IDialect {
 
-    private static final Pattern pattern = Pattern.compile("\\((.)*order by(.)*\\)");
+    private static final Pattern ORDER_BY_PATTERN = Pattern.compile("\\((.)*order by(.)*\\)");
+
+    private static final Pattern SELECT_PATTERN = Pattern.compile("(?i)select\\s+(distinct\\s+)?");
 
     public String getOrderByPart(String sql) {
         String order_by = "order by";
@@ -38,7 +40,7 @@ public class SQLServer2005Dialect implements IDialect {
         if (lastIndex == -1) {
             return StringPool.EMPTY;
         }
-        Matcher matcher = pattern.matcher(sql);
+        Matcher matcher = ORDER_BY_PATTERN.matcher(sql);
         if (!matcher.find()) {
             return sql.substring(lastIndex);
         }
@@ -51,20 +53,16 @@ public class SQLServer2005Dialect implements IDialect {
         StringBuilder pagingBuilder = new StringBuilder();
         String orderby = getOrderByPart(originalSql);
         String distinctStr = StringPool.EMPTY;
-
-        String loweredString = originalSql.toLowerCase();
         String sqlPartString = originalSql;
-        String trimStr = loweredString.trim();
-        if (trimStr.startsWith("select")) {
-            int index = loweredString.indexOf("select") + 6;
-            if (trimStr.startsWith("select distinct")) {
+        Matcher matcher = SELECT_PATTERN.matcher(originalSql);
+        if (matcher.find()) {
+            int index = matcher.end() - 1;
+            if (matcher.group().toLowerCase().contains("distinct")) {
                 distinctStr = "DISTINCT ";
-                index = loweredString.indexOf("select distinct") + 15;
             }
             sqlPartString = sqlPartString.substring(index);
         }
         pagingBuilder.append(sqlPartString);
-
         // if no ORDER BY is specified use fake ORDER BY field to avoid errors
         if (StringUtils.isBlank(orderby)) {
             orderby = "ORDER BY CURRENT_TIMESTAMP";

+ 31 - 0
mybatis-plus-extension/src/test/java/com/baomidou/mybatisplus/test/plugins/pagination/SQLServer2005DialectTest.java

@@ -22,6 +22,37 @@ public class SQLServer2005DialectTest {
             "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
         Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select *,(select 1) from test", 1, 10).getDialectSql(),
             "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("select   distinct   *,(select 1) from test", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select   distinct *,(select 1) from test", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("select   *,(select 1) from test", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select   *,(select 1) from test", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(select 1) from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("select * from test", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  * from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" select * from test", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  * from test) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("SELECT DISTINCT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" SELECT DISTINCT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT DISTINCT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("SELECT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" SELECT *,(SELECT 1) FROM TEST", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  *,(SELECT 1) FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql("SELECT * FROM TEST", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  * FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+        Assertions.assertEquals(sqlServer2005Dialect.buildPaginationSql(" SELECT * FROM TEST", 1, 10).getDialectSql(),
+            "WITH selectTemp AS (SELECT TOP 100 PERCENT  ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__,  * FROM TEST) SELECT * FROM selectTemp WHERE __row_number__ BETWEEN 2 AND 11 ORDER BY __row_number__");
+
     }
 
 }