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

自己動(dòng)手寫(xiě)的mybatis分頁(yè)插件(極其簡(jiǎn)單好用)

 更新時(shí)間:2016年11月12日 14:35:30   作者:李小拐  
最近做了個(gè)項(xiàng)目,需要用到mybatis分頁(yè)功能,網(wǎng)上找了很多插件,都不太合適,于是就自己動(dòng)手寫(xiě)了個(gè)mybatis分頁(yè)插件功能,非常不錯(cuò),代碼簡(jiǎn)單易懂,需要的朋友參考下吧

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

最重要的攔截器

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; 
/** 
* 
* 分頁(yè)攔截器,用于攔截需要進(jìn)行分頁(yè)查詢(xún)的操作,然后對(duì)其進(jìn)行分頁(yè)處理。 
* 利用攔截器實(shí)現(xiàn)Mybatis分頁(yè)的原理: 
* 要利用JDBC對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作就必須要有一個(gè)對(duì)應(yīng)的Statement對(duì)象,Mybatis在執(zhí)行Sql語(yǔ)句前就會(huì)產(chǎn)生一個(gè)包含Sql語(yǔ)句的Statement對(duì)象,而且對(duì)應(yīng)的Sql語(yǔ)句 
* 是在Statement之前產(chǎn)生的,所以我們就可以在它生成Statement之前對(duì)用來(lái)生成Statement的Sql語(yǔ)句下手。在Mybatis中Statement語(yǔ)句是通過(guò)RoutingStatementHandler對(duì)象的 
* prepare方法生成的。所以利用攔截器實(shí)現(xiàn)Mybatis分頁(yè)的一個(gè)思路就是攔截StatementHandler接口的prepare方法,然后在攔截器方法中把Sql語(yǔ)句改成對(duì)應(yīng)的分頁(yè)查詢(xún)Sql語(yǔ)句,之后再調(diào)用 
* StatementHandler對(duì)象的prepare方法,即調(diào)用invocation.proceed()。 
* 對(duì)于分頁(yè)而言,在攔截器里面我們還需要做的一個(gè)操作就是統(tǒng)計(jì)滿(mǎn)足當(dāng)前條件的記錄一共有多少,這是通過(guò)獲取到了原始的Sql語(yǔ)句后,把它改為對(duì)應(yīng)的統(tǒng)計(jì)語(yǔ)句再利用Mybatis封裝好的參數(shù)和設(shè) 
* 置參數(shù)的功能把Sql語(yǔ)句中的參數(shù)進(jìn)行替換,之后再執(zhí)行查詢(xún)記錄數(shù)的Sql語(yǔ)句進(jìn)行總記錄數(shù)的統(tǒng)計(jì)。 
* 
* 解釋一下插件中可能要用到的幾個(gè)類(lèi): 
* MetaObject:mybatis提供的一個(gè)基于返回獲取屬性值的對(duì)象的類(lèi) 
* BoundSql : 在這個(gè)里面可以獲取都要執(zhí)行的sql和執(zhí)行sql要用到的參數(shù) 
* MappedStatement : 這個(gè)可以得到當(dāng)前執(zhí)行的sql語(yǔ)句在xml文件中配置的id的值 
* RowBounds : 是mybatis內(nèi)存分頁(yè)要用到的。 
* ParameterHandler : 是mybatis中用來(lái)替換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{ 
//攔截分頁(yè)關(guān)鍵字 
private static final String SELECT_ID="page"; 
//插件運(yùn)行的代碼,它將代替原有的方法,要重寫(xiě)最重要的intercept了 
@Override 
public Object intercept(Invocation invocation) throws Throwable { 
if (invocation.getTarget() instanceof StatementHandler) { 
//這里我們有一個(gè)設(shè)定 如果查詢(xún)方法含有Page 就進(jìn)行分頁(yè) 其他方法無(wú)視 
//所以就要獲取方法名 
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"); 
//分頁(yè)參數(shù)作為參數(shù)對(duì)象parameterObject的一個(gè)屬性 
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"); 
// 重寫(xiě)sql 
String countSql=concatCountSql(sql); 
String pageSql=concatPageSql(sql,page); 
// System.out.println("重寫(xiě)的 count sql :"+countSql); 
System.out.println("重寫(xiě)的 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(); 
} 
// 攔截類(lèi)型StatementHandler,重寫(xiě)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(); 
} 
} 
分頁(yè)對(duì)象Page類(lèi)
[java] view plain copy
package com.dnkx.pojo; 
import java.util.HashMap; 
import java.util.Map; 
/** 
* 
* 分頁(yè)查詢(xún)輔助類(lèi) 
* @author 李小拐 2016年11月9日 13:55:37 
*/ 
public class Page { 
//----------分頁(yè)----------- 
private int pageSize;//每頁(yè)顯示條數(shù) 
private int pageCurrentPage;//第幾頁(yè) 
private int pageBegin;//開(kāi)始位置 
private int numCount;//總條數(shù) 
private int pageTotal;//總條數(shù) 
private String orderField = "";//控制排序頁(yè)面顯示的 
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")));//要查詢(xún)的頁(yè)數(shù) 
}else{ 
this.setPageCurrentPage(1);//設(shè)置初始值 
} 
if(map.get("numPerPage")!=null){ 
this.setPageSize(Integer.parseInt(map.get("numPerPage")));//每頁(yè)顯示條數(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)用方式

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對(duì)象放入?yún)?shù)集合(這個(gè)map是mybatis要用到的,包含查詢(xún)條件,排序,分頁(yè)等) 
//控制排序頁(yè)面顯示的 
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();//總頁(yè)數(shù) 
long b=System.currentTimeMillis(); 
System.out.println("---------耗時(shí):"+(b-a)+"ms"); 
return "basic/employee_list"; 
}

最后,spring里面配置插件

<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" /> 
<!-- 自動(dòng)掃描mapping.xml文件 --> 
<property name="mapperLocations" value="classpath:com/dnkx/mapping/*.xml"></property> 
<property name="plugins"> 
<ref bean="PageInterector"/> 
</property> 
</bean>

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

相關(guān)文章

  • java實(shí)現(xiàn)簡(jiǎn)單解析XML文件功能示例

    java實(shí)現(xiàn)簡(jiǎn)單解析XML文件功能示例

    這篇文章主要介紹了java實(shí)現(xiàn)簡(jiǎn)單解析XML文件功能,結(jié)合實(shí)例形式分析了java針對(duì)xml文件的讀取、遍歷節(jié)點(diǎn)及輸出等相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • Java實(shí)現(xiàn)解析JSON大文件JsonReader工具詳解

    Java實(shí)現(xiàn)解析JSON大文件JsonReader工具詳解

    這篇文章主要介紹了Java實(shí)現(xiàn)解析JSON大文件的工具JsonReader使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • Java中的雙重檢查(Double-Check)詳解

    Java中的雙重檢查(Double-Check)詳解

    這篇文章主要為大家詳細(xì)介紹了Java中的雙重檢查(Double-Check),感興趣的小伙伴們可以參考一下
    2016-02-02
  • 深入理解Java多線程與并發(fā)編程

    深入理解Java多線程與并發(fā)編程

    這篇文章主要介紹了Java多線程與并發(fā)編程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 解決Spring boot 嵌入的tomcat不啟動(dòng)問(wèn)題

    解決Spring boot 嵌入的tomcat不啟動(dòng)問(wèn)題

    這篇文章主要介紹了解決Spring boot 嵌入的tomcat不啟動(dòng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • Maven打包后找不到class文件的問(wèn)題

    Maven打包后找不到class文件的問(wèn)題

    本文主要介紹了Maven打包后找不到class文件的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 自定義注解實(shí)現(xiàn)Spring容器注入Bean方式(類(lèi)似于mybatis的@MapperScans)

    自定義注解實(shí)現(xiàn)Spring容器注入Bean方式(類(lèi)似于mybatis的@MapperScans)

    本文介紹了如何通過(guò)自定義注解@MyService和@MyServiceScans在SpringBoot項(xiàng)目中自動(dòng)將指定包下的類(lèi)注入Spring容器,詳細(xì)解釋了創(chuàng)建自定義注解、定義包掃描器ClassPathBeanDefinitionScanner的作用與實(shí)現(xiàn)
    2024-09-09
  • Maven打包所有依賴(lài)到一個(gè)可執(zhí)行jar中遇到的問(wèn)題

    Maven打包所有依賴(lài)到一個(gè)可執(zhí)行jar中遇到的問(wèn)題

    這篇文章主要給大家介紹了關(guān)于Maven打包所有依賴(lài)到一個(gè)可執(zhí)行jar中遇到的問(wèn)題,將依賴(lài)打入jar包,由于maven管理了所有的依賴(lài),所以將項(xiàng)目的代碼和依賴(lài)打成一個(gè)包對(duì)它來(lái)說(shuō)是順理成章的功能,需要的朋友可以參考下
    2023-10-10
  • JavaWeb 文件的上傳和下載功能簡(jiǎn)單實(shí)現(xiàn)代碼

    JavaWeb 文件的上傳和下載功能簡(jiǎn)單實(shí)現(xiàn)代碼

    這篇文章主要介紹了JavaWeb 文件的上傳和下載功能簡(jiǎn)單實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2017-04-04
  • 理解maven命令package、install、deploy的聯(lián)系與區(qū)別

    理解maven命令package、install、deploy的聯(lián)系與區(qū)別

    這篇文章主要介紹了理解maven命令package、install、deploy的聯(lián)系與區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論

萝北县| 澎湖县| 交口县| 上蔡县| 陈巴尔虎旗| 永新县| 龙海市| 兴仁县| 定西市| 卢氏县| 隆尧县| 福贡县| 泗洪县| 阳江市| 清丰县| 长宁县| 大关县| 吴旗县| 济源市| 泰兴市| 临潭县| 镇远县| 盐池县| 房产| 长宁区| 上饶市| 黄龙县| 伊川县| 蒙城县| 和静县| 津南区| 嘉鱼县| 阳山县| 嘉黎县| 沂水县| 开封市| 满城县| 衡山县| 德兴市| 通河县| 澄迈县|