佳木斯湛栽影视文化发展公司

主頁(yè) > 知識(shí)庫(kù) > MyBatis攔截器實(shí)現(xiàn)分頁(yè)功能的實(shí)現(xiàn)方法

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

熱門標(biāo)簽:地方門戶網(wǎng)站 Linux服務(wù)器 百度競(jìng)價(jià)排名 鐵路電話系統(tǒng) 網(wǎng)站排名優(yōu)化 服務(wù)外包 AI電銷 呼叫中心市場(chǎng)需求

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

前言:

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

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

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

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

  /**
   * 根據(jù)當(dāng)前對(duì)象中屬性值計(jì)算并設(shè)置相關(guān)屬性值
   */
  public void count() {
    // 計(jì)算總頁(yè)數(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)前頁(yè)數(shù)
    // 總頁(yè)數(shù)小于當(dāng)前頁(yè)數(shù),應(yīng)將當(dāng)前頁(yè)數(shù)設(shè)置為總頁(yè)數(shù)
    if(this.totalPage  this.currentPage) {
      this.currentPage = this.totalPage;
    }
    // 當(dāng)前頁(yè)數(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)鍵的攔截器實(shí)現(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;

/**
 * 分頁(yè)攔截器
 * 
 * @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");
    //通過(guò)MetaObject元數(shù)據(jù)取得方法名id:com.XXX.queryMessageListByPage
    String id = mappedStatement.getId();
    //匹配在mybatis中定義的與分頁(yè)有關(guān)的查詢id
    if (id.matches(".+ByPage$")) {
      //BoundSql中有原始的sql語(yǔ)句和對(duì)應(yīng)的查詢參數(shù)
      BoundSql boundSql = statementHandler.getBoundSql();
      MapString, Object> params = (MapString, 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)? 因?yàn)閿?shù)據(jù)表的列是從1開(kāi)始計(jì)數(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
   * 被攔截的對(duì)象
   */
  public Object plugin(Object target) {
    // 如果將攔截器類比喻為代購(gòu)票的公司,那this就是代購(gòu)業(yè)務(wù)員(進(jìn)入方法前是無(wú)代理購(gòu)票能力業(yè)務(wù)員,進(jìn)入后成為有代理能力的業(yè)務(wù)員)
    // 通過(guò)注解獲取攔截目標(biāo)的信息,如果不符合攔截要求就返回原目標(biāo),如果符合則使用動(dòng)態(tài)代理生成代理對(duì)象
    return Plugin.wrap(target, this);
  }

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

  }

}

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

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

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

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

!--pagination需要的腳本-->
%
  // 獲取請(qǐng)求的上下文
  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">

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

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

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

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

您可能感興趣的文章:
  • mybatisplus 的SQL攔截器實(shí)現(xiàn)關(guān)聯(lián)查詢功能
  • Mybatis自定義攔截器和插件開(kāi)發(fā)詳解
  • mybatis 自定義實(shí)現(xiàn)攔截器插件Interceptor示例
  • mybatis 通過(guò)攔截器打印完整的sql語(yǔ)句以及執(zhí)行結(jié)果操作
  • Mybatis Plugin攔截器開(kāi)發(fā)過(guò)程詳解
  • 簡(jiǎn)單了解mybatis攔截器實(shí)現(xiàn)原理及實(shí)例
  • mybatis攔截器實(shí)現(xiàn)通用權(quán)限字段添加的方法
  • Mybatis中攔截器的簡(jiǎn)單實(shí)現(xiàn)方法
  • mybatis攔截器與分頁(yè)插件實(shí)例教程
  • Mybatis Interceptor 攔截器的實(shí)現(xiàn)
  • MyBatis攔截器的原理與使用

標(biāo)簽:蘭州 仙桃 崇左 湖南 湘潭 黃山 衡水 銅川

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MyBatis攔截器實(shí)現(xiàn)分頁(yè)功能的實(shí)現(xiàn)方法》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    庄河市| 沭阳县| 麻城市| 巫溪县| 昆明市| 韩城市| 成武县| 丰宁| 西峡县| 松原市| 伊金霍洛旗| 盘山县| 格尔木市| 林口县| 嵩明县| 河津市| 巴南区| 那曲县| 孙吴县| 辉南县| 长沙市| 咸宁市| 厦门市| 诸暨市| 林甸县| 望奎县| 手游| 汉阴县| 申扎县| 武隆县| 祁阳县| 大安市| 镇安县| 永新县| 高尔夫| 清流县| 陕西省| 长治县| 穆棱市| 梁山县| 安宁市|