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

首頁 > 數(shù)據(jù)庫 > MySQL > 正文

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

2024-07-24 13:14:53
字體:
供稿:網(wǎng)友

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)教程知識閱讀請移步到MYSQL教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 江华| 丹寨县| 靖边县| 陇西县| 富顺县| 伽师县| 手游| 延寿县| 西城区| 陇川县| 苍南县| 珠海市| 黄浦区| 佳木斯市| 开远市| 青海省| 博罗县| 奉节县| 冷水江市| 江华| 张家口市| 阿勒泰市| 桂东县| 庄河市| 涪陵区| 鄂尔多斯市| 灌云县| 双桥区| 包头市| 新乡市| 肃北| 拉萨市| 册亨县| 白银市| 如皋市| 江津市| 吴堡县| 涞水县| 扎兰屯市| 泊头市| 巴彦淖尔市|