一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|

服務(wù)器之家 - 編程語言 - JAVA教程 - 自己動手寫的mybatis分頁插件(極其簡單好用)

自己動手寫的mybatis分頁插件(極其簡單好用)

2020-07-04 10:50李小拐 JAVA教程

最近做了個項目,需要用到mybatis分頁功能,網(wǎng)上找了很多插件,都不太合適,于是就自己動手寫了個mybatis分頁插件功能,非常不錯,代碼簡單易懂,需要的朋友參考下吧

剛開始項目,需要用到mybatis分頁,網(wǎng)上看了很多插件,其實實現(xiàn)原理基本都大同小異,但是大部分都只給了代碼,注釋不全,所以參考了很多篇文章(每篇文章偷一點代碼,評出來自己的,半抄襲),才自己模仿著寫出了一個適合自己項目的分頁插件,話不多說,直接上代碼,相比大部分文章,注釋算很完整了

最重要的攔截器

?
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
package com.dnkx.interceptor;
import java.sql.*;
import java.util.HashMap;
import java.util.Properties;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
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.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import com.dnkx.pojo.Page;
/**
*
* 分頁攔截器,用于攔截需要進行分頁查詢的操作,然后對其進行分頁處理。
* 利用攔截器實現(xiàn)Mybatis分頁的原理:
* 要利用JDBC對數(shù)據(jù)庫進行操作就必須要有一個對應(yīng)的Statement對象,Mybatis在執(zhí)行Sql語句前就會產(chǎn)生一個包含Sql語句的Statement對象,而且對應(yīng)的Sql語句
* 是在Statement之前產(chǎn)生的,所以我們就可以在它生成Statement之前對用來生成Statement的Sql語句下手。在Mybatis中Statement語句是通過RoutingStatementHandler對象的
* prepare方法生成的。所以利用攔截器實現(xiàn)Mybatis分頁的一個思路就是攔截StatementHandler接口的prepare方法,然后在攔截器方法中把Sql語句改成對應(yīng)的分頁查詢Sql語句,之后再調(diào)用
* StatementHandler對象的prepare方法,即調(diào)用invocation.proceed()。
* 對于分頁而言,在攔截器里面我們還需要做的一個操作就是統(tǒng)計滿足當前條件的記錄一共有多少,這是通過獲取到了原始的Sql語句后,把它改為對應(yīng)的統(tǒng)計語句再利用Mybatis封裝好的參數(shù)和設(shè)
* 置參數(shù)的功能把Sql語句中的參數(shù)進行替換,之后再執(zhí)行查詢記錄數(shù)的Sql語句進行總記錄數(shù)的統(tǒng)計。
*
* 解釋一下插件中可能要用到的幾個類:
* MetaObject:mybatis提供的一個基于返回獲取屬性值的對象的類
* BoundSql : 在這個里面可以獲取都要執(zhí)行的sql和執(zhí)行sql要用到的參數(shù)
* MappedStatement : 這個可以得到當前執(zhí)行的sql語句在xml文件中配置的id的值
* RowBounds : 是mybatis內(nèi)存分頁要用到的。
* ParameterHandler : 是mybatis中用來替換sql中?出現(xiàn)的值的.
*
* @author 李小拐 2016年11月9日 10:59:04
*/
@Intercepts({
@Signature(type=StatementHandler.class,method="prepare",args={Connection.class}),
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class PageInterceptor implements Interceptor{
//攔截分頁關(guān)鍵字
private static final String SELECT_ID="page";
//插件運行的代碼,它將代替原有的方法,要重寫最重要的intercept了
@Override
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getTarget() instanceof StatementHandler) {
//這里我們有一個設(shè)定 如果查詢方法含有Page 就進行分頁 其他方法無視
//所以就要獲取方法名
StatementHandler statementHandler=(StatementHandler)invocation.getTarget();
MetaObject metaObject=SystemMetaObject.forObject(statementHandler);
MappedStatement mappedStatement=(MappedStatement)metaObject.getValue("delegate.mappedStatement");
String selectId=mappedStatement.getId();
String methorName=selectId.substring(selectId.lastIndexOf(".")+1).toLowerCase();
//然后判斷下 如果含有Page 就獲取sql
if(methorName.contains(SELECT_ID)){
BoundSql boundSql=(BoundSql)metaObject.getValue("delegate.boundSql");
//分頁參數(shù)作為參數(shù)對象parameterObject的一個屬性
String sql=boundSql.getSql();
System.out.println("獲取到的sql:"+sql);
HashMap<String, Object> map=(HashMap<String, Object>)(boundSql.getParameterObject());
//Page page=(Page)(boundSql.getParameterObject());
Page page=(Page)map.get("page");
// 重寫sql
String countSql=concatCountSql(sql);
String pageSql=concatPageSql(sql,page);
// System.out.println("重寫的 count sql :"+countSql);
System.out.println("重寫的 select sql :"+pageSql);
Connection connection = (Connection) invocation.getArgs()[0];
PreparedStatement countStmt = null;
ResultSet rs = null;
int totalCount = 0;
try {
countStmt = connection.prepareStatement(countSql);
rs = countStmt.executeQuery();
if (rs.next()) {
totalCount = rs.getInt(1);
}
} catch (SQLException e) {
System.out.println("Ignore this exception"+e);
} finally {
try {
rs.close();
countStmt.close();
} catch (SQLException e) {
System.out.println("Ignore this exception"+ e);
}
}
metaObject.setValue("delegate.boundSql.sql", pageSql);
//綁定count
page.setNumCount(totalCount);
}
}
return invocation.proceed();
}
// 攔截類型StatementHandler,重寫plugin方法
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
}else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
}
//改造sql
public String concatCountSql(String sql){
//StringBuffer sb=new StringBuffer("select count(*) from ");
/*sql=sql.toLowerCase();
if(sql.lastIndexOf("order")>sql.lastIndexOf(")")){
sb.append(sql.substring(sql.indexOf("from")+4, sql.lastIndexOf("order")));
}else{
sb.append(sql.substring(sql.indexOf("from")+4));
}*/
StringBuffer sb=new StringBuffer();
sql=sql.toLowerCase();
if(sql.lastIndexOf("order")>0){
sql=sql.substring(0,sql.indexOf("order"));
}
sb.append("select count(*) from ("+sql+") tmp");
return sb.toString();
}
public String concatPageSql(String sql,Page page){
StringBuffer sb=new StringBuffer();
sb.append(sql);
sb.append(" limit ").append(page.getPageBegin()).append(" , ").append(page.getPageSize());
return sb.toString();
}
}
分頁對象Page類
[java] view plain copy
package com.dnkx.pojo;
import java.util.HashMap;
import java.util.Map;
/**
*
* 分頁查詢輔助類
* @author 李小拐 2016年11月9日 13:55:37
*/
public class Page {
//----------分頁-----------
private int pageSize;//每頁顯示條數(shù)
private int pageCurrentPage;//第幾頁
private int pageBegin;//開始位置
private int numCount;//總條數(shù)
private int pageTotal;//總條數(shù)
private String orderField = "";//控制排序頁面顯示的
private String orderDirection = "";
public Page(){
}
public Page(int pageSize, int pageCurrentPage) {
super();
this.pageSize = pageSize;
this.pageCurrentPage = pageCurrentPage;
}
public Page(Map<String, String> map){
if(map.get("pageNum")!=null){
this.setPageCurrentPage(this.pageCurrentPage = Integer.parseInt(map.get("pageNum")));//要查詢的頁數(shù)
}else{
this.setPageCurrentPage(1);//設(shè)置初始值
}
if(map.get("numPerPage")!=null){
this.setPageSize(Integer.parseInt(map.get("numPerPage")));//每頁顯示條數(shù)
}else{
this.setPageSize(5);//設(shè)置初始值
}
if(map.get("orderField")!=null){
this.setOrderField(map.get("orderField"));
}
if(map.get("orderDirection")!=null){
this.setOrderDirection(map.get("orderDirection"));
}
}
public int getPageCurrentPage() {
return pageCurrentPage;
}
public void setPageCurrentPage(int pageCurrentPage) {
this.pageCurrentPage = pageCurrentPage;
}
public int getNumCount() {
return numCount;
}
public void setNumCount(int numCount) {
this.numCount = numCount;
}
public int getPageTotal() {
return (numCount%pageSize>0)?(numCount/pageSize+1):(numCount/pageSize);
}
public void setPageTotal(int pageTotal) {
this.pageTotal = pageTotal;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPageBegin() {
return pageSize*(pageCurrentPage-1);
}
public void setPageBegin(int pageBegin) {
this.pageBegin = pageBegin;
}
public String getOrderField() {
return orderField;
}
public void setOrderField(String orderField) {
this.orderField = orderField;
}
public String getOrderDirection() {
return orderDirection;
}
public void setOrderDirection(String orderDirection) {
this.orderDirection = orderDirection;
}
public static Page getPage(int pageSize, int pageCurrentPage){
return new Page(pageSize,pageCurrentPage);
}
public static Page getPage(Map map){
return new Page(map);
}
}

Controller里面調(diào)用方式

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public String list(HttpServletRequest request) {
long a=System.currentTimeMillis();
HashMap<String,Object> map=GetRequestMap.getMap(request);//自己封裝的方法,取request的參數(shù)
Page page= Page.getPage(map);//初始化page
map.put("page", page);//把page對象放入?yún)?shù)集合(這個map是mybatis要用到的,包含查詢條件,排序,分頁等)
//控制排序頁面顯示的
map.put(map.get("orderField")+"", map.get("orderDirection"));
List<Employee> list=employeeService.getListPage(map);
request.setAttribute("emlist", list);
request.setAttribute("page", page);
request.setAttribute("map", map);
//取page相關(guān)屬性
page.getNumCount();//總條數(shù)
page.getPageTotal();//總頁數(shù)
long b=System.currentTimeMillis();
System.out.println("---------耗時:"+(b-a)+"ms");
return "basic/employee_list";
}

最后,spring里面配置插件

?
1
2
3
4
5
6
7
8
9
10
<bean id="PageInterector" class="com.dnkx.interceptor.PageInterceptor"></bean>
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自動掃描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:com/dnkx/mapping/*.xml"></property>
<property name="plugins">
<ref bean="PageInterector"/>
</property>
</bean>

好了,到此結(jié)束,本文僅供參考!也期待大神提意見

原文鏈接:http://blog.csdn.net/yttea/article/details/53139796

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人影院观看 | 精品欧美男同同性videos | 国产免费一区二区三区免费视频 | 精品久久综合一区二区 | 女教师巨大乳孔中文字幕免费 | 久久久无码精品亚洲欧美 | 久久成人免费大片 | 国产综合图区 | 美女脱了内裤让男生玩屁股 | 五月天精品视频播放在线观看 | 国产裸露片段精华合集链接 | 性关系免费视频 | 果冻传媒 天美 麻豆 | 亚洲理论视频 | 国产人成激情视频在线观看 | 日韩亚洲国产激情在线观看 | 日韩美一区二区三区 | 女人扒开下面让男人桶爽视频 | 肉色欧美久久久久久久蜜桃 | 香蕉tv亚洲专区在线观看 | japanesen女同 | 欧美一区二区三区精品国产 | 99福利在线观看 | 水蜜臀| 男人添女人 | 亚洲色图欧美偷拍 | 国产成人刺激视频在线观看 | 亚洲欧美日韩特级毛片 | 久久综合香蕉久久久久久久 | 九九精品99久久久香蕉 | 青涩体验在线观看未删减 | 国产码一区二区三区 | 武侠艳妇屈辱的张开双腿 | 亚洲福利天堂网福利在线观看 | 视频在线免费看 | 色婷婷影院在线视频免费播放 | 男女乱淫真视频播放网站 | 久久久精品成人免费看 | 99热成人精品免费久久 | 婷婷色天使在线视频观看 | 欧美一区二区日韩一区二区 |