激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Mysql - MyBatis攔截器實現分頁功能的實現方法

MyBatis攔截器實現分頁功能的實現方法

2020-08-18 16:17旭旭同學 Mysql

這篇文章主要介紹了MyBatis攔截器實現分頁功能的實現方法的相關資料,希望通過本文大家能夠實現這樣的方法,需要的朋友可以參考下

MyBatis攔截器實現分頁功能的實現方法

前言:

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

除了業務代碼之外,需要寫的東西不多,提幾個關鍵的:

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
 * 分頁對應的實體類
 */
public class Page {
  /**
   * 總條數
   */
  private int totalNumber;
  /**
   * 當前第幾頁
   */
  private int currentPage;
  /**
   * 總頁數
   */
  private int totalPage;
  /**
   * 每頁顯示條數
   */
  private int pageNumber = 5;
  /**
   * 數據庫中limit的參數,從第幾條開始取
   */
  private int dbIndex;
  /**
   * 數據庫中limit的參數,一共取多少條
   */
  private int dbNumber;
 
  /**
   * 根據當前對象中屬性值計算并設置相關屬性值
   */
  public void count() {
    // 計算總頁數
    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;
 
    // 設置當前頁數
    // 總頁數小于當前頁數,應將當前頁數設置為總頁數
    if(this.totalPage < this.currentPage) {
      this.currentPage = this.totalPage;
    }
    // 當前頁數小于1設置為1
    if(this.currentPage < 1) {
      this.currentPage = 1;
    }
 
    // 設置limit的參數
    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、關鍵的攔截器實現

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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元數據取得方法名id:com.XXX.queryMessageListByPage
    String id = mappedStatement.getId();
    //匹配在mybatis中定義的與分頁有關的查詢id
    if (id.matches(".+ByPage$")) {
      //BoundSql中有原始的sql語句和對應的查詢參數
      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)? 因為數據表的列是從1開始計數
        page.setTotalNumber(rs.getInt(1));
        System.out.println("攔截器得知page的記錄總數為:" + 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就是代購業務員(進入方法前是無代理購票能力業務員,進入后成為有代理能力的業務員)
    // 通過注解獲取攔截目標的信息,如果不符合攔截要求就返回原目標,如果符合則使用動態代理生成代理對象
    return Plugin.wrap(target, this);
  }
 
  public void setProperties(Properties properties) {
    // TODO Auto-generated method stub
 
  }
 
}

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

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

Dao層相關的mapper.xml里面的sql語句不用做改動。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!--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">
 
// 點擊分頁按鈕以后觸發的動作
function handlePaginationClick(new_page_index, pagination_container) {
<!--從stuForm表單提交當前頁的參數.可以使用restful方式,讓springmvc使用@PathVariable關鍵字定義的形參去接。這2個參數是分頁控件自己提供的,不需要我們去自己找,但是計數從0開始,而我們后臺分頁計數從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, // 當前顯示第幾頁數據
    num_display_entries:8, // 分頁顯示的條目數
    next_text:"下一頁",
    prev_text:"上一頁",
    num_edge_entries:2, // 連接分頁主體,顯示的條目數
    callback:handlePaginationClick(當前頁,分頁div的id), //執行的回調函數
    load_first_page:false //防止頁面一直刷新( 這條非常重要!)
  });
});
</script>
<!-- 這部分用c:forEach標簽打印查詢結果的表格-->
<!--分頁控件名稱-->
<div id="News-Pagination"></div>

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

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

原文鏈接:http://blog.csdn.net/kaka0509/article/details/70195804

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 无遮挡一级毛片视频 | 全黄裸片武则天一级第4季 偿还电影免费看 | 国产91极品| 国产chinesehd精品91 | 免费永久看羞羞片网站入口 | 国产一区在线视频观看 | 中文字幕在线观看91 | 久久国产精品久久精品国产演员表 | 欧美一级做 | 欧美a在线观看 | 国产日韩亚洲 | 久久精品成人影院 | 久久亚洲成人 | 国产精品成人一区二区三区电影毛片 | wwwxxx免费视频 | 看免费黄色大片 | 亚洲综合一区在线观看 | 自拍偷拍999| 日本不卡一二三区 | 狠狠久久伊人中文字幕 | 日日干天天摸 | 韩国十九禁高潮床戏在线观看 | 国产欧美日韩久久久 | 男女污污视频网站 | 国产毛片网 | 成人毛片免费看 | 性猛交ⅹxxx乱巴西 欧美日韩1区2区3区 | 一级毛片在线视频 | 精品亚洲国产视频 | 国产成人精品一区二区仙踪林 | 日韩视频中文 | 久久里面有精品 | 国产视频在线播放 | 2021av视频| 国产午夜精品在线 | 亚洲欧美国产精品va在线观看 | 成人午夜视频在线观看免费 | 成人在线视频播放 | 中文字幕网址 | 亚洲成人在线视频网 | 精品国产一区二区在线 |