最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis攔截器實現(xiàn)分頁功能的實現(xiàn)方法

 更新時間:2017年10月30日 09:46:41   作者:旭旭同學(xué)  
這篇文章主要介紹了MyBatis攔截器實現(xiàn)分頁功能的實現(xiàn)方法的相關(guān)資料,希望通過本文大家能夠?qū)崿F(xiàn)這樣的方法,需要的朋友可以參考下

MyBatis攔截器實現(xiàn)分頁功能的實現(xiàn)方法

前言:

首先說下實現(xiàn)原理。使用攔截器攔截原始的sql,然后加上分頁查詢的關(guān)鍵字和屬性,拼裝成新的sql語句再交給mybatis去執(zhí)行。

除了業(yè)務(wù)代碼之外,需要寫的東西不多,提幾個關(guān)鍵的:

1、分頁對象Page類。給該對象設(shè)置一個當(dāng)前頁數(shù)(前端給)、總記錄數(shù)(攔截器內(nèi)賦值)2個參數(shù),他就能幫你計算出分頁sql語句用的2個參數(shù)。

/**
 * 分頁對應(yīng)的實體類
 */
public class Page {
  /**
   * 總條數(shù)
   */
  private int totalNumber;
  /**
   * 當(dāng)前第幾頁
   */
  private int currentPage;
  /**
   * 總頁數(shù)
   */
  private int totalPage;
  /**
   * 每頁顯示條數(shù)
   */
  private int pageNumber = 5;
  /**
   * 數(shù)據(jù)庫中l(wèi)imit的參數(shù),從第幾條開始取
   */
  private int dbIndex;
  /**
   * 數(shù)據(jù)庫中l(wèi)imit的參數(shù),一共取多少條
   */
  private int dbNumber;

  /**
   * 根據(jù)當(dāng)前對象中屬性值計算并設(shè)置相關(guān)屬性值
   */
  public void count() {
    // 計算總頁數(shù)
    int totalPageTemp = this.totalNumber / this.pageNumber;
    int plus = (this.totalNumber % this.pageNumber) == 0 ? 0 : 1;
    totalPageTemp = totalPageTemp + plus;
    if(totalPageTemp <= 0) {
      totalPageTemp = 1;
    }
    this.totalPage = totalPageTemp;

    // 設(shè)置當(dāng)前頁數(shù)
    // 總頁數(shù)小于當(dāng)前頁數(shù),應(yīng)將當(dāng)前頁數(shù)設(shè)置為總頁數(shù)
    if(this.totalPage < this.currentPage) {
      this.currentPage = this.totalPage;
    }
    // 當(dāng)前頁數(shù)小于1設(shè)置為1
    if(this.currentPage < 1) {
      this.currentPage = 1;
    }

    // 設(shè)置limit的參數(shù)
    this.dbIndex = (this.currentPage - 1) * this.pageNumber;
    this.dbNumber = this.pageNumber;
  }

  public int getTotalNumber() {
    return totalNumber;
  }

  public void setTotalNumber(int totalNumber) {
    this.totalNumber = totalNumber;
    this.count();
  }

  public int getCurrentPage() {
    return currentPage;
  }

  public void setCurrentPage(int currentPage) {
    this.currentPage = currentPage;
  }

  public int getTotalPage() {
    return totalPage;
  }

  public void setTotalPage(int totalPage) {
    this.totalPage = totalPage;
  }

  public int getPageNumber() {
    return pageNumber;
  }

  public void setPageNumber(int pageNumber) {
    this.pageNumber = pageNumber;
    this.count();
  }

  public int getDbIndex() {
    return dbIndex;
  }

  public void setDbIndex(int dbIndex) {
    this.dbIndex = dbIndex;
  }

  public int getDbNumber() {
    return dbNumber;
  }

  public void setDbNumber(int dbNumber) {
    this.dbNumber = dbNumber;
  }
}

2、關(guān)鍵的攔截器實現(xiàn)

package com.imooc.interceptor;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Properties;

import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
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.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import com.imooc.entity.Page;

/**
 * 分頁攔截器
 * 
 * @author Skye
 *
 */
@Intercepts({
    @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class }) })
public class PageInterceptor implements Interceptor {

  public Object intercept(Invocation invocation) throws Throwable {
    StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
    MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
        SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
    MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
    //通過MetaObject元數(shù)據(jù)取得方法名id:com.XXX.queryMessageListByPage
    String id = mappedStatement.getId();
    //匹配在mybatis中定義的與分頁有關(guān)的查詢id
    if (id.matches(".+ByPage$")) {
      //BoundSql中有原始的sql語句和對應(yīng)的查詢參數(shù)
      BoundSql boundSql = statementHandler.getBoundSql();
      Map<String, Object> params = (Map<String, Object>) boundSql.getParameterObject();
      Page page = (Page) params.get("page");
      String sql = boundSql.getSql();
      String countSql = "select count(*)from (" + sql + ")a";
      Connection connection = (Connection) invocation.getArgs()[0];
      PreparedStatement countStatement = connection.prepareStatement(countSql);
      ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
      parameterHandler.setParameters(countStatement);
      ResultSet rs = countStatement.executeQuery();
      if (rs.next()) {
        //為什么是getInt(1)? 因為數(shù)據(jù)表的列是從1開始計數(shù)
        page.setTotalNumber(rs.getInt(1));
        System.out.println("攔截器得知page的記錄總數(shù)為:" + page.getTotalNumber());
      }
      String pageSql = sql + " limit " + page.getDbIndex() + "," + page.getDbNumber();
      metaObject.setValue("delegate.boundSql.sql", pageSql);
    }
    return invocation.proceed();
  }

  /**
   * @param target
   * 被攔截的對象
   */
  public Object plugin(Object target) {
    // 如果將攔截器類比喻為代購票的公司,那this就是代購業(yè)務(wù)員(進入方法前是無代理購票能力業(yè)務(wù)員,進入后成為有代理能力的業(yè)務(wù)員)
    // 通過注解獲取攔截目標(biāo)的信息,如果不符合攔截要求就返回原目標(biāo),如果符合則使用動態(tài)代理生成代理對象
    return Plugin.wrap(target, this);
  }

  public void setProperties(Properties properties) {
    // TODO Auto-generated method stub

  }

}

3、mybatis-config.xml里面注冊自己寫的攔截器

 <!-- 自定義的分頁攔截器 -->
  <plugins>
    <plugin interceptor="你寫的攔截器全類名">
    </plugin>
  </plugins>

Dao層相關(guān)的mapper.xml里面的sql語句不用做改動。

4、前端需要給后端一個顯示哪一頁的參數(shù),通過service層組裝查詢參數(shù)之后交給MyBatis去查分頁數(shù)據(jù),我定義的分頁DAO接口返回的數(shù)據(jù)是一個list,包含了分頁查詢結(jié)果。前端可以用jquery_pagination插件去實現(xiàn)分頁的展示,具體去官方github看怎么設(shè)置吧。

<!--pagination需要的腳本-->
<%
  // 獲取請求的上下文
  String context = request.getContextPath();
%>
<link href="../css/pagination.css" rel="external nofollow" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../js/jquery-1.11.3.js"></script>
<script type="text/javascript" src="../js/jquery.pagination.js"></script>
<script type="text/javascript">

// 點擊分頁按鈕以后觸發(fā)的動作
function handlePaginationClick(new_page_index, pagination_container) {
<!--從stuForm表單提交當(dāng)前頁的參數(shù).可以使用restful方式,讓springmvc使用@PathVariable關(guān)鍵字定義的形參去接。這2個參數(shù)是分頁控件自己提供的,不需要我們?nèi)プ约赫遥怯嫈?shù)從0開始,而我們后臺分頁計數(shù)從1開始,因此要手動加1。 -->
  $("#stuForm").attr("action", "你定義的分頁查詢url/"+(new_page_index+1));
  $("#stuForm").submit();
  return false;
}

$(function(){
  $("#News-Pagination").pagination(${result.totalRecord}, {
    items_per_page:${result.pageSize}, // 每頁顯示多少條記錄
    current_page:${result.currentPage} - 1, // 當(dāng)前顯示第幾頁數(shù)據(jù)
    num_display_entries:8, // 分頁顯示的條目數(shù)
    next_text:"下一頁",
    prev_text:"上一頁",
    num_edge_entries:2, // 連接分頁主體,顯示的條目數(shù)
    callback:handlePaginationClick(當(dāng)前頁,分頁div的id), //執(zhí)行的回調(diào)函數(shù)
    load_first_page:false //防止頁面一直刷新( 這條非常重要!)
  });
});
</script>
<!-- 這部分用c:forEach標(biāo)簽打印查詢結(jié)果的表格-->
<!--分頁控件名稱-->
<div id="News-Pagination"></div>

寫這篇總結(jié)的目的是希望形成一個分頁功能的整體解決方案(前端+后端都涵蓋到)。4月17、18日開始我會寫一個小系統(tǒng)將前段時間所學(xué)都用上,完了之后會回來更新這篇文章里面不正確的地方。

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • SQL實現(xiàn)LeetCode(177.第N高薪水)

    SQL實現(xiàn)LeetCode(177.第N高薪水)

    這篇文章主要介紹了SQL實現(xiàn)LeetCode(177.第N高薪水),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • MySQL表排序規(guī)則不同錯誤問題分析

    MySQL表排序規(guī)則不同錯誤問題分析

    這篇文章主要介紹了MySQL表排序規(guī)則不同錯誤問題分析,小編覺得挺不錯的,這里分享給大家,供各位參考。
    2017-10-10
  • 安裝mysql8.0.11及修改root密碼、連接navicat for mysql的思路詳解

    安裝mysql8.0.11及修改root密碼、連接navicat for mysql的思路詳解

    這篇文章主要介紹了安裝mysql8.0.11以及修改root密碼、連接navicat for mysql,需要的朋友可以參考下
    2018-06-06
  • MySQL如何查詢數(shù)據(jù)庫中所有表名及注釋等信息

    MySQL如何查詢數(shù)據(jù)庫中所有表名及注釋等信息

    這篇文章主要介紹了MySQL如何查詢數(shù)據(jù)庫中所有表名及注釋等信息問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • 詳解MySQL數(shù)據(jù)庫insert和update語句

    詳解MySQL數(shù)據(jù)庫insert和update語句

    用于操作數(shù)據(jù)庫的SQL一般分為兩種,一種是查詢語句,也就是我們所說的SELECT語句,另外一種就是更新語句,也叫做數(shù)據(jù)操作語句。接下來通過本文給大家介紹MySQL數(shù)據(jù)庫insert和update語句,需要的朋友一起學(xué)習(xí)吧
    2016-04-04
  • 在windows10上安裝mysql詳細(xì)圖文教程

    在windows10上安裝mysql詳細(xì)圖文教程

    這篇文章主要介紹了在windows10上安裝mysql詳細(xì)圖文教程,本文介紹的非常詳細(xì),具有參考借鑒價值,感興趣的朋友一起看看吧
    2016-09-09
  • mysql8如何設(shè)置不區(qū)分大小寫ubuntu20

    mysql8如何設(shè)置不區(qū)分大小寫ubuntu20

    這篇文章主要介紹了mysql8如何設(shè)置不區(qū)分大小寫ubuntu20問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • mysql視圖原理與用法實例詳解

    mysql視圖原理與用法實例詳解

    這篇文章主要介紹了mysql視圖原理與用法,結(jié)合實例形式詳細(xì)分析了mysql視圖的概念、原理、使用方法及操作注意事項,需要的朋友可以參考下
    2020-04-04
  • MySQL8.0修改密碼的正確姿勢分享

    MySQL8.0修改密碼的正確姿勢分享

    如果當(dāng)初設(shè)置了一個很復(fù)雜的數(shù)據(jù)庫密碼,是很可能忘記的,下面這篇文章主要給大家介紹了關(guān)于MySQL8.0修改密碼的正確姿勢,需要的朋友可以參考下
    2022-03-03
  • 教你為MySQL數(shù)據(jù)庫換擋加速

    教你為MySQL數(shù)據(jù)庫換擋加速

    如果你是個賽車手,并且按一下按鈕就能夠立即更換引擎而不需要把車開到車庫里去換,那會是什么感覺呢?MySQL數(shù)據(jù)庫為開發(fā)人員所做的就好像是按按鈕換引擎;它讓你選擇數(shù)據(jù)庫引擎,并給你一條簡單的途徑來切換它。
    2010-02-02

最新評論

桂林市| 阿城市| 庆安县| 都昌县| 布尔津县| 红河县| 彰化县| 霸州市| 钟祥市| 克山县| 扶沟县| 贡嘎县| 东港市| 襄城县| 芒康县| 衡山县| 安仁县| 松潘县| 浮山县| 朝阳县| 沁水县| 泊头市| 屏东县| 芜湖县| 大余县| 双辽市| 普陀区| 黔东| 长子县| 宽甸| 彩票| 黄冈市| 双桥区| 万年县| 沽源县| 嘉定区| 宜兰市| 贵阳市| 天津市| 安丘市| 丰都县|