<plugins> < plugin interceptor = "com.has.core.page.PaginationInterceptor" /> </plugins>
2. [文件] PaginationInterceptor.java
@Intercepts ({ @Signature (type = StatementHandler. class,method = "prepare",args = { Connection. class }) }) public class PaginationInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); Boundsql boundsql = statementHandler.getBoundsql(); MetaObject MetaStatementHandler = MetaObject.forObject(statementHandler); RowBounds rowBounds = (RowBounds) MetaStatementHandler.getValue( "delegate.rowBounds" ); if (rowBounds == null || rowBounds == RowBounds.DEFAULT) { return invocation.proceed(); } Configuration configuration = (Configuration) MetaStatementHandler.getValue( "delegate.configuration" ); Dialect.Type databaseType = null ; try { databaseType = Dialect.Type.valueOf(configuration.getvariables().getProperty( "dialect" ).toupperCase()); } catch (Exception e) { } if (databaseType == null ) { throw new RuntimeException( "the value of the dialect property in configuration.xml is not defined : " + configuration.getvariables().getProperty( "dialect" )); } Dialect dialect = null ; switch (databaseType) { case MysqL: dialect = new MysqL5Dialect(); break ; case ORACLE: dialect = new OracleDialect(); break ; } String originalsql = (String) MetaStatementHandler.getValue( "delegate.boundsql.sql" ); MetaStatementHandler.setValue( "delegate.boundsql.sql",dialect.getLimitString(originalsql,rowBounds.getoffset(),rowBounds.getLimit())); MetaStatementHandler.setValue( "delegate.rowBounds.offset",RowBounds.NO_ROW_OFFSET); MetaStatementHandler.setValue( "delegate.rowBounds.limit",RowBounds.NO_ROW_LIMIT); return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target,this ); } @Override public void setProperties(Properties properties) { } }
3. [文件] Dialect.java
/** * 数据库方言定义 * */ public abstract class Dialect { public static enum Type { MysqL,ORACLE } public abstract String getLimitString(String sql,int skipResults,int maxResults); }
/** * MysqL方言分页类 */ public class MysqL5Dialect extends Dialect { protected static final String sql_END_DELIMITER = ";" ; public String getLimitString(String sql,boolean hasOffset) { return MysqL5PageHepler.getLimitString(sql,- 1,- 1 ); } public String getLimitString(String sql,int offset,int limit) { return MysqL5PageHepler.getLimitString(sql,offset,limit); } public boolean supportsLimit() { return true ; } }
5. [文件] OracleDialect.java
package com.chyjr.has.core.page.dialect; /** * oracel方言分页 * */ public class OracleDialect extends Dialect { public String getLimitString(String sql,int limit) { // Todo 未实现 return ""; } }
import java.util.regex.Matcher; import java.util.regex.Pattern; /** * MysqL分页工具类 */ 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 || !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 limit) { querySelect = getLinesql(querySelect); // String sql = querySelect.replaceAll("[^\\s,]+\\.","") + " limit " + // offset + "," + limit; 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; } }
2. [图片] Mybatis.jpg