国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

java分頁攔截類實現sql自動分頁

2019-11-26 13:31:41
字體:
來源:轉載
供稿:網友

本文實例為大家分享了完整的java分頁攔截類,供大家參考,具體內容如下

package com.opms.interceptor;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;import org.apache.ibatis.executor.parameter.ParameterHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.logging.Log;import org.apache.ibatis.logging.LogFactory;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Plugin;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.factory.DefaultObjectFactory;import org.apache.ibatis.reflection.factory.ObjectFactory;import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;import org.apache.ibatis.session.RowBounds;import com.wifi.core.page.Page;/** * 通過攔截<code>StatementHandler</code>的<code>prepare</code>方法,重寫sql語句實現物理分頁。 * 老規矩,簽名里要攔截的類型只能是接口。 *  * @author 湖畔微風 *  */@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})public class PageInterceptor implements Interceptor { /**  * 日志  */ private static final Log logger = LogFactory.getLog(PageInterceptor.class); /**  * 聲明對象  */ private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory(); /**  * 聲明對象  */ private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory(); /**  * 數據庫類型(默認為mysql)  */ private static String defaultDialect = "mysql";  /**  * 需要攔截的ID(正則匹配)  */ private static String defaultPageSqlId = ".*4Page$";  /**  * 數據庫類型(默認為mysql)   */ private static String dialect = "";  /**  * 需要攔截的ID(正則匹配)  */ private static String pageSqlId = "";  /**  * @param invocation 參數  * @return Object  * @throws Throwable 拋出異常  */ public Object intercept(Invocation invocation) throws Throwable {  StatementHandler statementHandler = (StatementHandler) invocation.getTarget();  MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY,    DEFAULT_OBJECT_WRAPPER_FACTORY);  // 分離代理對象鏈(由于目標類可能被多個攔截器攔截,從而形成多次代理,通過下面的兩次循環可以分離出最原始的的目標類)  while (metaStatementHandler.hasGetter("h")) {   Object object = metaStatementHandler.getValue("h");   metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);  }  // 分離最后一個代理對象的目標類  while (metaStatementHandler.hasGetter("target")) {   Object object = metaStatementHandler.getValue("target");   metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);  }  dialect=defaultDialect;pageSqlId=defaultPageSqlId;  /* Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");  dialect = configuration.getVariables().getProperty("dialect");  if (null == dialect || "".equals(dialect)) {   logger.warn("Property dialect is not setted,use default 'mysql' ");   dialect = defaultDialect;  }  pageSqlId = configuration.getVariables().getProperty("pageSqlId");  if (null == pageSqlId || "".equals(pageSqlId)) {   logger.warn("Property pageSqlId is not setted,use default '.*Page$' ");   pageSqlId = defaultPageSqlId;  }*/  MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");  // 只重寫需要分頁的sql語句。通過MappedStatement的ID匹配,默認重寫以Page結尾的MappedStatement的sql  if (mappedStatement.getId().matches(pageSqlId)) {   BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");   Object parameterObject = boundSql.getParameterObject();   if (parameterObject == null) {    throw new NullPointerException("parameterObject is null!");   } else {    Object obj = metaStatementHandler      .getValue("delegate.boundSql.parameterObject.page");    // 傳入了page參數且需要開啟分頁時    if(obj!=null&&obj instanceof Page &&((Page)obj).isPagination()){     Page page = (Page) metaStatementHandler       .getValue("delegate.boundSql.parameterObject.page");     String sql = boundSql.getSql();     // 重寫sql     String pageSql = buildPageSql(sql, page);     metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);     // 采用物理分頁后,就不需要mybatis的內存分頁了,所以重置下面的兩個參數     metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);     metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);     Connection connection = (Connection) invocation.getArgs()[0];     // 重設分頁參數里的總頁數等     setPageParameter(sql, connection, mappedStatement, boundSql, page);    }   }  }  // 將執行權交給下一個攔截器  return invocation.proceed(); } /**  * 從數據庫里查詢總的記錄數并計算總頁數,回寫進分頁參數<code>PageParameter</code>,這樣調用者就可用通過 分頁參數  * <code>PageParameter</code>獲得相關信息。  *   * @param sql 參數  * @param connection 連接  * @param mappedStatement 參數  * @param boundSql 綁定sql  * @param page 頁  */ private void setPageParameter(String sql, Connection connection, MappedStatement mappedStatement,   BoundSql boundSql, Page page) {  // 記錄總記錄數  String countSql = "select count(0) from (" + sql + ") as total";  PreparedStatement countStmt = null;  ResultSet rs = null;  try {   countStmt = connection.prepareStatement(countSql);   BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,     boundSql.getParameterMappings(), boundSql.getParameterObject());   setParameters(countStmt, mappedStatement, countBS, boundSql.getParameterObject());   rs = countStmt.executeQuery();   int totalCount = 0;   if (rs.next()) {    totalCount = rs.getInt(1);   }   page.setTotalCount(totalCount);   page.init(page.getCurPage(), page.getPageSize(), totalCount);  } catch (SQLException e) {   logger.error("Ignore this exception", e);  } finally {   try {    rs.close();   } catch (SQLException e) {    logger.error("Ignore this exception", e);   }   try {    countStmt.close();   } catch (SQLException e) {    logger.error("Ignore this exception", e);   }  } } /**  * 對SQL參數(?)設值  *   * @param ps 參數  * @param mappedStatement 參數  * @param boundSql 綁定sql  * @param parameterObject 參數對象  * @throws SQLException 拋出sql異常  */ private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql,   Object parameterObject) throws SQLException {  ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);  parameterHandler.setParameters(ps); } /**  * 根據數據庫類型,生成特定的分頁sql  *   * @param sql 餐宿  * @param page 頁  * @return String  */ private String buildPageSql(String sql, Page page) {  if (page != null) {   StringBuilder pageSql = new StringBuilder();   if ("mysql".equals(dialect)) {    pageSql = buildPageSqlForMysql(sql, page);   } else if ("oracle".equals(dialect)) {    pageSql = buildPageSqlForOracle(sql, page);   } else {    return sql;   }   return pageSql.toString();  } else {   return sql;  } } /**  * mysql的分頁語句  *   * @param sql 參數  * @param page 頁  * @return String  */ public StringBuilder buildPageSqlForMysql(String sql, Page page) {  StringBuilder pageSql = new StringBuilder(100);  String beginrow = String.valueOf((page.getCurPage() - 1) * page.getPageSize());  pageSql.append(sql);  pageSql.append(" limit " + beginrow + "," + page.getPageSize());  return pageSql; } /**  * 參考hibernate的實現完成oracle的分頁  *   * @param sql 參數  * @param page 參數  * @return String  */ public StringBuilder buildPageSqlForOracle(String sql, Page page) {  StringBuilder pageSql = new StringBuilder(100);  String beginrow = String.valueOf((page.getCurPage() - 1) * page.getPageSize());  String endrow = String.valueOf(page.getCurPage() * page.getPageSize());  pageSql.append("select * from ( select temp.*, rownum row_id from ( ");  pageSql.append(sql);  pageSql.append(" ) temp where rownum <= ").append(endrow);  pageSql.append(") where row_id > ").append(beginrow);  return pageSql; } /**  * @param target 參數  * @return Object  */ public Object plugin(Object target) {  // 當目標類是StatementHandler類型時,才包裝目標類,否者直接返回目標本身,減少目標被代理的次數  if (target instanceof StatementHandler) {   return Plugin.wrap(target, this);  } else {   return target;  } } /**  * @param properties 參數  */ public void setProperties(Properties properties) { }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 原平市| 中宁县| 互助| 浏阳市| 江阴市| 崇阳县| 襄城县| 龙山县| 黑河市| 布尔津县| 彭水| 崇义县| 墨玉县| 云和县| 武冈市| 塔城市| 张家港市| 新化县| 邵东县| 昌乐县| 丰城市| 明水县| 石家庄市| 锦州市| 鄂托克前旗| 秦皇岛市| 宣武区| 都兰县| 社会| 十堰市| 铜梁县| 慈溪市| 巴中市| 塘沽区| 南京市| 依安县| 临猗县| 三台县| 嘉义市| 措勤县| 綦江县|