亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java分頁攔截類實(shí)現(xiàn)sql自動分頁

 更新時(shí)間:2016年11月24日 11:28:27   作者:zcj2860755  
這篇文章主要為大家詳細(xì)介紹了java分頁攔截類可以實(shí)現(xiàn)sql自動分頁,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

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語句實(shí)現(xiàn)物理分頁。
 * 老規(guī)矩,簽名里要攔截的類型只能是接口。
 * 
 * @author 湖畔微風(fēng)
 * 
 */
@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();
 /**
  * 數(shù)據(jù)庫類型(默認(rèn)為mysql)
  */
 private static String defaultDialect = "mysql"; 
 /**
  * 需要攔截的ID(正則匹配)
  */
 private static String defaultPageSqlId = ".*4Page$"; 
 /**
  * 數(shù)據(jù)庫類型(默認(rèn)為mysql) 
  */
 private static String dialect = ""; 
 /**
  * 需要攔截的ID(正則匹配)
  */
 private static String pageSqlId = ""; 
 /**
  * @param invocation 參數(shù)
  * @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);
  // 分離代理對象鏈(由于目標(biāo)類可能被多個(gè)攔截器攔截,從而形成多次代理,通過下面的兩次循環(huán)可以分離出最原始的的目標(biāo)類)
  while (metaStatementHandler.hasGetter("h")) {
   Object object = metaStatementHandler.getValue("h");
   metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
  }
  // 分離最后一個(gè)代理對象的目標(biāo)類
  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匹配,默認(rèn)重寫以Page結(jié)尾的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參數(shù)且需要開啟分頁時(shí)
    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的內(nèi)存分頁了,所以重置下面的兩個(gè)參數(shù)
     metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
     metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
     Connection connection = (Connection) invocation.getArgs()[0];
     // 重設(shè)分頁參數(shù)里的總頁數(shù)等
     setPageParameter(sql, connection, mappedStatement, boundSql, page);
    }
   }
  }
  // 將執(zhí)行權(quán)交給下一個(gè)攔截器
  return invocation.proceed();
 }

 /**
  * 從數(shù)據(jù)庫里查詢總的記錄數(shù)并計(jì)算總頁數(shù),回寫進(jìn)分頁參數(shù)<code>PageParameter</code>,這樣調(diào)用者就可用通過 分頁參數(shù)
  * <code>PageParameter</code>獲得相關(guān)信息。
  * 
  * @param sql 參數(shù)
  * @param connection 連接
  * @param mappedStatement 參數(shù)
  * @param boundSql 綁定sql
  * @param page 頁
  */
 private void setPageParameter(String sql, Connection connection, MappedStatement mappedStatement,
   BoundSql boundSql, Page page) {
  // 記錄總記錄數(shù)
  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參數(shù)(?)設(shè)值
  * 
  * @param ps 參數(shù)
  * @param mappedStatement 參數(shù)
  * @param boundSql 綁定sql
  * @param parameterObject 參數(shù)對象
  * @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);
 }

 /**
  * 根據(jù)數(shù)據(jù)庫類型,生成特定的分頁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 參數(shù)
  * @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的實(shí)現(xiàn)完成oracle的分頁
  * 
  * @param sql 參數(shù)
  * @param page 參數(shù)
  * @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 參數(shù)
  * @return Object
  */
 public Object plugin(Object target) {
  // 當(dāng)目標(biāo)類是StatementHandler類型時(shí),才包裝目標(biāo)類,否者直接返回目標(biāo)本身,減少目標(biāo)被代理的次數(shù)
  if (target instanceof StatementHandler) {
   return Plugin.wrap(target, this);
  } else {
   return target;
  }
 }
 /**
  * @param properties 參數(shù)
  */
 public void setProperties(Properties properties) {
 }

}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot項(xiàng)目的測試類實(shí)例解析

    SpringBoot項(xiàng)目的測試類實(shí)例解析

    這篇文章主要介紹了SpringBoot項(xiàng)目的測試類實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java老手該當(dāng)心的13個(gè)錯(cuò)誤

    Java老手該當(dāng)心的13個(gè)錯(cuò)誤

    這篇文章主要介紹了Java老手該當(dāng)心的13個(gè)錯(cuò)誤,需要的朋友可以參考下
    2015-04-04
  • idea out目錄與target目錄的區(qū)別詳解

    idea out目錄與target目錄的區(qū)別詳解

    這篇文章主要介紹了idea out目錄與target目錄的區(qū)別詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 深入理解MyBatis中的一級緩存與二級緩存

    深入理解MyBatis中的一級緩存與二級緩存

    這篇文章主要給大家深入的介紹了關(guān)于MyBatis中一級緩存與二級緩存的相關(guān)資料,文中詳細(xì)介紹MyBatis中一級緩存與二級緩存的工作原理及使用,對大家具有一定的參考性學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2017-06-06
  • 深入講解SPI?在?Spring?中的應(yīng)用

    深入講解SPI?在?Spring?中的應(yīng)用

    這篇文章主要介紹了深入講解SPI在Spring中的應(yīng)用,SPI是Java內(nèi)置的一種服務(wù)提供發(fā)現(xiàn)機(jī)制,可以用來提高框架的擴(kuò)展性,主要用于框架的開發(fā)中
    2022-06-06
  • mybatis攔截器與分頁插件實(shí)例教程

    mybatis攔截器與分頁插件實(shí)例教程

    Mybatis攔截器常常會被用來進(jìn)行分頁處理。所以下面這篇文章主要給大家介紹了關(guān)于mybatis攔截器與分頁插件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用mybatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Java實(shí)現(xiàn)高校教務(wù)系統(tǒng)

    Java實(shí)現(xiàn)高校教務(wù)系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)高校教務(wù)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • java使用htmlparser提取網(wǎng)頁純文本例子

    java使用htmlparser提取網(wǎng)頁純文本例子

    這篇文章主要介紹了java使用htmlparser提取網(wǎng)頁純文本例子,需要的朋友可以參考下
    2014-04-04
  • SpringBoot各種參數(shù)校驗(yàn)的實(shí)例教程

    SpringBoot各種參數(shù)校驗(yàn)的實(shí)例教程

    經(jīng)常需要提供接口與用戶交互(獲取數(shù)據(jù)、上傳數(shù)據(jù)等),由于這個(gè)過程需要用戶進(jìn)行相關(guān)的操作,為了避免出現(xiàn)一些錯(cuò)誤的數(shù)據(jù)等,一般需要對數(shù)據(jù)進(jìn)行校驗(yàn),下面這篇文章主要給大家介紹了關(guān)于SpringBoot各種參數(shù)校驗(yàn)的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • 詳解Spring MVC如何測試Controller(使用springmvc mock測試)

    詳解Spring MVC如何測試Controller(使用springmvc mock測試)

    這篇文章主要介紹了詳解Spring MVC如何測試Controller(使用springmvc mock測試),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12

最新評論