浏览代码

数据库分页dialect重构

zhouchenglin 6 年之前
父节点
当前提交
944410f6e2

+ 92 - 6
src/main/java/net/chenlin/dp/common/support/orm/dialect/Dialect.java

@@ -1,12 +1,11 @@
 package net.chenlin.dp.common.support.orm.dialect;
 
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 /**
  * 数据库方言抽象类
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午11:09:57
+ * @author zhouchenglin[yczclcn@163.com]
  */
 public abstract class Dialect {
 
@@ -24,6 +23,93 @@ public abstract class Dialect {
      * @param sql
      * @return
      */
-    public abstract String getCountString(String sql);
+    public String getCountString(String sql) {
+        sql = getLineSql(sql);
+        int orderIndex = getLastOrderInsertPoint(sql);
+
+        int formIndex = getAfterFormInsertPoint(sql);
+        String select = sql.substring(0, formIndex);
+
+        // 如果SELECT 中包含 DISTINCT 只能在外层包含COUNT
+        if (select.toLowerCase().indexOf("select distinct") != -1 || sql.toLowerCase().indexOf("group by") != -1) {
+            return new StringBuffer(sql.length()).append("select count(1) count from (").append(sql.substring(0, orderIndex)).append(" ) t").toString();
+        } else {
+            return new StringBuffer(sql.length()).append("select count(1) count ").append(sql.substring(formIndex, orderIndex)).toString();
+        }
+    }
+
+    /**
+     * 得到最后一个Order By的插入点位置
+     *
+     * @return 返回最后一个Order By插入点的位置
+     */
+    protected int getLastOrderInsertPoint(String querySelect) {
+        int orderIndex = querySelect.toLowerCase().lastIndexOf("order by");
+        if (orderIndex == -1) {
+            orderIndex = querySelect.length();
+        }
+        if (!isBracketCanPartnership(querySelect.substring(orderIndex, querySelect.length()))) {
+            throw new RuntimeException("My SQL 分页必须要有Order by 语句!");
+        }
+        return orderIndex;
+    }
+
+    /**
+     * 将SQL语句变成一条语句,并且每个单词的间隔都是1个空格
+     *
+     * @param sql
+     *            SQL语句
+     * @return 如果sql是NULL返回空,否则返回转化后的SQL
+     */
+    protected String getLineSql(String sql) {
+        return sql.replaceAll("[\r\n]", " ").replaceAll("\\s{2,}", " ");
+    }
+
+    /**
+     * 得到SQL第一个正确的FROM的的插入点
+     */
+    protected int getAfterFormInsertPoint(String querySelect) {
+        String regex = "\\s+FROM\\s+";
+        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(querySelect);
+        while (matcher.find()) {
+            int fromStartIndex = matcher.start(0);
+            String text = querySelect.substring(0, fromStartIndex);
+            if (isBracketCanPartnership(text)) {
+                return fromStartIndex;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * 判断括号"()"是否匹配,并不会判断排列顺序是否正确
+     *
+     * @param text
+     *            要判断的文本
+     * @return 如果匹配返回TRUE,否则返回FALSE
+     */
+    protected boolean isBracketCanPartnership(String text) {
+        if (text == null || (getIndexOfCount(text, '(') != getIndexOfCount(text, ')'))) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 得到一个字符在另一个字符串中出现的次数
+     *
+     * @param text
+     *            文本
+     * @param ch
+     *            字符
+     */
+    protected int getIndexOfCount(String text, char ch) {
+        int count = 0;
+        for (int i = 0; i < text.length(); i++) {
+            count = (text.charAt(i) == ch) ? count + 1 : count;
+        }
+        return count;
+    }
 
 }

+ 1 - 5
src/main/java/net/chenlin/dp/common/support/orm/dialect/DialectFactory.java

@@ -4,11 +4,7 @@ import org.apache.ibatis.session.Configuration;
 
 /**
  * 数据库方言工厂,产生方言对象
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午11:06:30
+ * @author zhouchenglin[yczclcn@163.com]
  */
 public class DialectFactory {
 

+ 9 - 12
src/main/java/net/chenlin/dp/common/support/orm/dialect/MSDialect.java

@@ -2,23 +2,20 @@ package net.chenlin.dp.common.support.orm.dialect;
 
 /**
  * MSSQL 数据库方言
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午110650
+ * @author zhouchenglin[yczclcn@163.com]
  */
 public class MSDialect extends Dialect {
 
-    protected static final String SQL_END_DELIMITER = ";";
-
     @Override
     public String getLimitString(String sql, int offset, int limit) {
-        return MSPageHepler.getLimitString(sql, offset, limit);
-    }
 
-    @Override
-    public String getCountString(String sql) {
-        return MSPageHepler.getCountString(sql);
+        sql = getLineSql(sql);
+        int selectIndex = sql.toUpperCase().lastIndexOf("SELECT");
+        if (selectIndex > -1) {
+            sql = sql.substring(0, selectIndex) + "SELECT TOP " + (limit + offset) + sql.substring(selectIndex + 6);
+        }
+        return "SELECT * FROM(SELECT ROW_NUMBER () OVER (ORDER BY getdate()) rownum,* FROM( " + sql + " ) A ) B WHERE B.rownum > " + offset + " AND B.rownum <= "
+                + (limit + offset);
     }
+
 }

+ 0 - 128
src/main/java/net/chenlin/dp/common/support/orm/dialect/MSPageHepler.java

@@ -1,128 +0,0 @@
-package net.chenlin.dp.common.support.orm.dialect;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * MSPageHepler
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url: www.chenlintech.com
- * @date 2017年8月8日 上午11:07:02
- */
-public class MSPageHepler {
-    /**
-     * 得到查询总数的sql
-     */
-    public static String getCountString(String querySelect) {
-
-        querySelect = getLineSql(querySelect);
-        int orderIndex = getLastOrderInsertPoint(querySelect);
-
-        int formIndex = getAfterFormInsertPoint(querySelect);
-        String select = querySelect.substring(0, formIndex);
-
-        // 如果SELECT 中包含 DISTINCT 只能在外层包含COUNT
-        if (select.toLowerCase().indexOf("select distinct") != -1 || querySelect.toLowerCase().indexOf("group by") != -1) {
-            return new StringBuffer(querySelect.length()).append("select count(1) count from (").append(querySelect.substring(0, orderIndex)).append(" ) t").toString();
-        } else {
-            return new StringBuffer(querySelect.length()).append("select count(1) count ").append(querySelect.substring(formIndex, orderIndex)).toString();
-        }
-    }
-
-    /**
-     * 得到最后一个Order By的插入点位置
-     * 
-     * @return 返回最后一个Order By插入点的位置
-     */
-    private static int getLastOrderInsertPoint(String querySelect) {
-        int orderIndex = querySelect.toLowerCase().lastIndexOf("order by");
-        if (orderIndex == -1) {
-            orderIndex = querySelect.length();
-        }
-        if (!isBracketCanPartnership(querySelect.substring(orderIndex, querySelect.length()))) {
-            throw new RuntimeException("My SQL 分页必须要有Order by 语句!");
-        }
-        return orderIndex;
-    }
-
-    /**
-     * 得到分页的SQL
-     * 
-     * @param offset
-     *            偏移量
-     * @param limit
-     *            位置
-     * @return 分页SQL
-     */
-    public static String getLimitString(String querySelect, int offset, int limit) {
-        querySelect = getLineSql(querySelect);
-        int selectIndex = querySelect.toUpperCase().lastIndexOf("SELECT");
-        if (selectIndex > -1) {
-            querySelect = querySelect.substring(0, selectIndex) + "SELECT TOP " + (limit + offset) + querySelect.substring(selectIndex + 6);
-        }
-        String sql = "SELECT * FROM(SELECT ROW_NUMBER () OVER (ORDER BY getdate()) rownum,* FROM( " + querySelect + " ) A ) B WHERE B.rownum > " + offset + " AND B.rownum <= "
-                + (limit + offset);
-        return sql;
-
-    }
-
-    /**
-     * 将SQL语句变成一条语句,并且每个单词的间隔都是1个空格
-     * 
-     * @param sql
-     *            SQL语句
-     * @return 如果sql是NULL返回空,否则返回转化后的SQL
-     */
-    private static String getLineSql(String sql) {
-        return sql.replaceAll("[\r\n]", " ").replaceAll("\\s{2,}", " ");
-    }
-
-    /**
-     * 得到SQL第一个正确的FROM的的插入点
-     */
-    private static int getAfterFormInsertPoint(String querySelect) {
-        String regex = "\\s+FROM\\s+";
-        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
-        Matcher matcher = pattern.matcher(querySelect);
-        while (matcher.find()) {
-            int fromStartIndex = matcher.start(0);
-            String text = querySelect.substring(0, fromStartIndex);
-            if (isBracketCanPartnership(text)) {
-                return fromStartIndex;
-            }
-        }
-        return 0;
-    }
-
-    /**
-     * 判断括号"()"是否匹配,并不会判断排列顺序是否正确
-     * 
-     * @param text
-     *            要判断的文本
-     * @return 如果匹配返回TRUE,否则返回FALSE
-     */
-    private static boolean isBracketCanPartnership(String text) {
-        if (text == null || (getIndexOfCount(text, '(') != getIndexOfCount(text, ')'))) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 得到一个字符在另一个字符串中出现的次数
-     * 
-     * @param text
-     *            文本
-     * @param ch
-     *            字符
-     */
-    private static int getIndexOfCount(String text, char ch) {
-        int count = 0;
-        for (int i = 0; i < text.length(); i++) {
-            count = (text.charAt(i) == ch) ? count + 1 : count;
-        }
-        return count;
-    }
-}

+ 3 - 12
src/main/java/net/chenlin/dp/common/support/orm/dialect/MySql5Dialect.java

@@ -2,23 +2,14 @@ package net.chenlin.dp.common.support.orm.dialect;
 
 /**
  * MySQL数据库方言
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午11:07:12
+ * @author zhouchenglin[yczclcn@163.com]
  */
 public class MySql5Dialect extends Dialect {
 
-    protected static final String SQL_END_DELIMITER = ";";
-
     @Override
     public String getLimitString(String sql, int offset, int limit) {
-        return MySql5PageHepler.getLimitString(sql, offset, limit);
+        sql = getLineSql(sql);
+        return (sql + " limit " + offset + " ," + limit);
     }
 
-    @Override
-    public String getCountString(String sql) {
-        return MySql5PageHepler.getCountString(sql);
-    }
 }

+ 0 - 126
src/main/java/net/chenlin/dp/common/support/orm/dialect/MySql5PageHepler.java

@@ -1,126 +0,0 @@
-package net.chenlin.dp.common.support.orm.dialect;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * MySql5PageHepler
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午11:07:21
- */
-public class MySql5PageHepler {
-    /**
-     * 得到查询总数的sql
-     */
-    public static String getCountString(String querySelect) {
-
-        querySelect = getLineSql(querySelect);
-        int orderIndex = getLastOrderInsertPoint(querySelect);
-
-        int formIndex = getAfterFormInsertPoint(querySelect);
-        String select = querySelect.substring(0, formIndex);
-
-        // 如果SELECT 中包含 DISTINCT 只能在外层包含COUNT
-        if (select.toLowerCase().indexOf("select distinct") != -1 || querySelect.toLowerCase().indexOf("group by") != -1) {
-            return new StringBuffer(querySelect.length()).append("select count(1) count from (").append(querySelect.substring(0, orderIndex)).append(" ) t").toString();
-        } else {
-            return new StringBuffer(querySelect.length()).append("select count(1) count ").append(querySelect.substring(formIndex, orderIndex)).toString();
-        }
-    }
-
-    /**
-     * 得到最后一个Order By的插入点位置
-     * 
-     * @return 返回最后一个Order By插入点的位置
-     */
-    private static int getLastOrderInsertPoint(String querySelect) {
-        int orderIndex = querySelect.toLowerCase().lastIndexOf("order by");
-        if (orderIndex == -1) {
-            orderIndex = querySelect.length();
-        }
-        if (!isBracketCanPartnership(querySelect.substring(orderIndex, querySelect.length()))) {
-            throw new RuntimeException("My SQL 分页必须要有Order by 语句!");
-        }
-        return orderIndex;
-    }
-
-    /**
-     * 得到分页的SQL
-     * 
-     * @param offset
-     *            偏移量
-     * @param limit
-     *            位置
-     * @return 分页SQL
-     */
-    public static String getLimitString(String querySelect, int offset, int limit) {
-
-        querySelect = getLineSql(querySelect);
-
-        String sql = querySelect + " limit " + offset + " ," + limit;
-
-        return sql;
-
-    }
-
-    /**
-     * 将SQL语句变成一条语句,并且每个单词的间隔都是1个空格
-     * 
-     * @param sql
-     *            SQL语句
-     * @return 如果sql是NULL返回空,否则返回转化后的SQL
-     */
-    private static String getLineSql(String sql) {
-        return sql.replaceAll("[\r\n]", " ").replaceAll("\\s{2,}", " ");
-    }
-
-    /**
-     * 得到SQL第一个正确的FROM的的插入点
-     */
-    private static int getAfterFormInsertPoint(String querySelect) {
-        String regex = "\\s+FROM\\s+";
-        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
-        Matcher matcher = pattern.matcher(querySelect);
-        while (matcher.find()) {
-            int fromStartIndex = matcher.start(0);
-            String text = querySelect.substring(0, fromStartIndex);
-            if (isBracketCanPartnership(text)) {
-                return fromStartIndex;
-            }
-        }
-        return 0;
-    }
-
-    /**
-     * 判断括号"()"是否匹配,并不会判断排列顺序是否正确
-     * 
-     * @param text
-     *            要判断的文本
-     * @return 如果匹配返回TRUE,否则返回FALSE
-     */
-    private static boolean isBracketCanPartnership(String text) {
-        if (text == null || (getIndexOfCount(text, '(') != getIndexOfCount(text, ')'))) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 得到一个字符在另一个字符串中出现的次数
-     * 
-     * @param text
-     *            文本
-     * @param ch
-     *            字符
-     */
-    private static int getIndexOfCount(String text, char ch) {
-        int count = 0;
-        for (int i = 0; i < text.length(); i++) {
-            count = (text.charAt(i) == ch) ? count + 1 : count;
-        }
-        return count;
-    }
-}

+ 1 - 10
src/main/java/net/chenlin/dp/common/support/orm/dialect/OracleDialect.java

@@ -2,11 +2,7 @@ package net.chenlin.dp.common.support.orm.dialect;
 
 /**
  * oracle方言
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午11:07:29
+ * @author zhouchenglin[yczclcn@163.com]
  */
 public class OracleDialect extends Dialect {
 
@@ -35,9 +31,4 @@ public class OracleDialect extends Dialect {
         return pagingSelect.toString();
     }
 
-    @Override
-    public String getCountString(String sql) {
-        // TODO Oracle分页查询
-        return null;
-    }
 }

+ 3 - 12
src/main/java/net/chenlin/dp/common/support/orm/dialect/PostgreDialect.java

@@ -2,23 +2,14 @@ package net.chenlin.dp.common.support.orm.dialect;
 
 /**
  * Postgre 数据库 方言
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午11:07:36
+ * @author zhouchenglin[yczclcn@163.com]
  */
 public class PostgreDialect extends Dialect {
 
-    protected static final String SQL_END_DELIMITER = ";";
-
     @Override
     public String getLimitString(String sql, int offset, int limit) {
-        return PostgrePageHepler.getLimitString(sql, offset, limit);
+        sql = getLineSql(sql);
+        return (sql + " LIMIT " + limit + " OFFSET " + offset);
     }
 
-    @Override
-    public String getCountString(String sql) {
-        return PostgrePageHepler.getCountString(sql);
-    }
 }

+ 0 - 121
src/main/java/net/chenlin/dp/common/support/orm/dialect/PostgrePageHepler.java

@@ -1,121 +0,0 @@
-package net.chenlin.dp.common.support.orm.dialect;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * PostgrePageHepler
- *
- * @author ZhouChenglin
- * @email yczclcn@163.com
- * @url www.chenlintech.com
- * @date 2017年8月8日 上午11:07:46
- */
-public class PostgrePageHepler {
-    /**
-     * 得到查询总数的sql
-     */
-    public static String getCountString(String querySelect) {
-        querySelect = getLineSql(querySelect);
-        int orderIndex = getLastOrderInsertPoint(querySelect);
-
-        int formIndex = getAfterFormInsertPoint(querySelect);
-        String select = querySelect.substring(0, formIndex);
-
-        // 如果SELECT 中包含 DISTINCT 只能在外层包含COUNT
-        if (select.toLowerCase().indexOf("select distinct") != -1 || querySelect.toLowerCase().indexOf("group by") != -1) {
-            return new StringBuffer(querySelect.length()).append("select count(1) count from (").append(querySelect.substring(0, orderIndex)).append(" ) t").toString();
-        } else {
-            return new StringBuffer(querySelect.length()).append("select count(1) count ").append(querySelect.substring(formIndex, orderIndex)).toString();
-        }
-    }
-
-    /**
-     * 得到最后一个Order By的插入点位置
-     * 
-     * @return 返回最后一个Order By插入点的位置
-     */
-    private static int getLastOrderInsertPoint(String querySelect) {
-        int orderIndex = querySelect.toLowerCase().lastIndexOf("order by");
-        if (orderIndex == -1) {
-            orderIndex = querySelect.length();
-        }
-        if (!isBracketCanPartnership(querySelect.substring(orderIndex, querySelect.length()))) {
-            throw new RuntimeException("Postgre 分页必须要有Order by 语句!");
-        }
-        return orderIndex;
-    }
-
-    /**
-     * 得到分页的SQL
-     * 
-     * @param offset
-     *            偏移量
-     * @param limit
-     *            位置
-     * @return 分页SQL
-     */
-    public static String getLimitString(String querySelect, int offset, int limit) {
-        querySelect = getLineSql(querySelect);
-        String sql = querySelect + " LIMIT " + limit + " OFFSET " + offset;
-        return sql;
-    }
-
-    /**
-     * 将SQL语句变成一条语句,并且每个单词的间隔都是1个空格
-     * 
-     * @param sql
-     *            SQL语句
-     * @return 如果sql是NULL返回空,否则返回转化后的SQL
-     */
-    private static String getLineSql(String sql) {
-        return sql.replaceAll("[\r\n]", " ").replaceAll("\\s{2,}", " ");
-    }
-
-    /**
-     * 得到SQL第一个正确的FROM的的插入点
-     */
-    private static int getAfterFormInsertPoint(String querySelect) {
-        String regex = "\\s+FROM\\s+";
-        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
-        Matcher matcher = pattern.matcher(querySelect);
-        while (matcher.find()) {
-            int fromStartIndex = matcher.start(0);
-            String text = querySelect.substring(0, fromStartIndex);
-            if (isBracketCanPartnership(text)) {
-                return fromStartIndex;
-            }
-        }
-        return 0;
-    }
-
-    /**
-     * 判断括号"()"是否匹配,并不会判断排列顺序是否正确
-     * 
-     * @param text
-     *            要判断的文本
-     * @return 如果匹配返回TRUE,否则返回FALSE
-     */
-    private static boolean isBracketCanPartnership(String text) {
-        if (text == null || (getIndexOfCount(text, '(') != getIndexOfCount(text, ')'))) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * 得到一个字符在另一个字符串中出现的次数
-     * 
-     * @param text
-     *            文本
-     * @param ch
-     *            字符
-     */
-    private static int getIndexOfCount(String text, char ch) {
-        int count = 0;
-        for (int i = 0; i < text.length(); i++) {
-            count = (text.charAt(i) == ch) ? count + 1 : count;
-        }
-        return count;
-    }
-}

+ 2 - 2
src/main/java/net/chenlin/dp/common/support/orm/plugins/PaginationStatementHandlerInterceptor.java

@@ -5,6 +5,8 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.util.Properties;
 
+import net.chenlin.dp.common.support.orm.dialect.Dialect;
+import net.chenlin.dp.common.support.orm.dialect.DialectFactory;
 import org.apache.ibatis.executor.parameter.ParameterHandler;
 import org.apache.ibatis.executor.statement.StatementHandler;
 import org.apache.ibatis.mapping.BoundSql;
@@ -26,8 +28,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import net.chenlin.dp.common.entity.Page;
-import net.chenlin.dp.common.support.orm.dialect.Dialect;
-import net.chenlin.dp.common.support.orm.dialect.DialectFactory;
 
 /**
  * PaginationStatementHandlerInterceptor