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

首頁(yè) > 編程 > Java > 正文

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

2019-11-26 13:34:23
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

剛開始項(xiàng)目,需要用到mybatis分頁(yè),網(wǎng)上看了很多插件,其實(shí)實(shí)現(xiàn)原理基本都大同小異,但是大部分都只給了代碼,注釋不全,所以參考了很多篇文章(每篇文章偷一點(diǎn)代碼,評(píng)出來(lái)自己的,半抄襲),才自己模仿著寫出了一個(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è)查詢的操作,然后對(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ǔ)句是通過RoutingStatementHandler對(duì)象的 * prepare方法生成的。所以利用攔截器實(shí)現(xiàn)Mybatis分頁(yè)的一個(gè)思路就是攔截StatementHandler接口的prepare方法,然后在攔截器方法中把Sql語(yǔ)句改成對(duì)應(yīng)的分頁(yè)查詢Sql語(yǔ)句,之后再調(diào)用 * StatementHandler對(duì)象的prepare方法,即調(diào)用invocation.proceed()。 * 對(duì)于分頁(yè)而言,在攔截器里面我們還需要做的一個(gè)操作就是統(tǒng)計(jì)滿足當(dāng)前條件的記錄一共有多少,這是通過獲取到了原始的Sql語(yǔ)句后,把它改為對(duì)應(yīng)的統(tǒng)計(jì)語(yǔ)句再利用Mybatis封裝好的參數(shù)和設(shè) * 置參數(shù)的功能把Sql語(yǔ)句中的參數(shù)進(jìn)行替換,之后再執(zhí)行查詢記錄數(shù)的Sql語(yǔ)句進(jìn)行總記錄數(shù)的統(tǒng)計(jì)。 * * 解釋一下插件中可能要用到的幾個(gè)類: * MetaObject:mybatis提供的一個(gè)基于返回獲取屬性值的對(duì)象的類 * 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)行的代碼,它將代替原有的方法,要重寫最重要的intercept了 @Override public Object intercept(Invocation invocation) throws Throwable { if (invocation.getTarget() instanceof StatementHandler) { //這里我們有一個(gè)設(shè)定 如果查詢方法含有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"); // 重寫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(); } } 分頁(yè)對(duì)象Page類[java] view plain copypackage com.dnkx.pojo; import java.util.HashMap; import java.util.Map; /** * * 分頁(yè)查詢輔助類 * @author 李小拐 2016年11月9日 13:55:37 */ public class Page { //----------分頁(yè)----------- private int pageSize;//每頁(yè)顯示條數(shù) private int pageCurrentPage;//第幾頁(yè) private int pageBegin;//開始位置 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")));//要查詢的頁(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要用到的,包含查詢條件,排序,分頁(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é)束,本文僅供參考!也期待大神提意見

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 临颍县| 开远市| 德惠市| 乡城县| 吴旗县| 鄂尔多斯市| 财经| 文化| 城市| 晋宁县| 内江市| 绥中县| 府谷县| 象山县| 隆子县| 茂名市| 金昌市| 泰兴市| 花垣县| 安宁市| 梅州市| 珠海市| 伊春市| 四平市| 富源县| 漯河市| 通州区| 阜新市| 桑日县| 桦川县| 谢通门县| 清流县| 岳普湖县| 佛山市| 珲春市| 泸州市| 高碑店市| 岳西县| 徐州市| 磴口县| 阿克苏市|