版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、近期由于工作需要,想要開發(fā)一版能夠滿足多數人員使用的mybatis分頁攔截器,在網上查找了很多資料并結合自己的一些理解,開發(fā)出了以下一版簡單的代碼。起初想要遵循江湖慣例,通過各個層級間傳遞分頁參數來實現目標,但開發(fā)過程中發(fā)現這樣針對已開發(fā)好的代碼影響較大(需要修改前端到后端的所有代碼),成本較高。然后在此基礎上提升了目標 1、 降低業(yè)務代碼侵入性。2、 減少原有代碼的修改。3、 減少調用人員開發(fā)量。雖然最終版本在初次配置使用時會有一些繁瑣,但后續(xù)擴展非常有優(yōu)勢。廢話少說,上配置過程和代碼。使用方法1、 將java文件放置到某個文件夾下2、 添加maven依賴 mybatis 主要是攔截器部分,
2、可自行在內部資源庫中搜索或在網上搜索3、 配置spring mybatis部分。4、 根據需要修改spring-mybatis文件。5、 Mapper文件中配置以”ForPage”結尾的查詢,如<select id="selectByTableNameForPage" resultMap="BaseResultMap"> select distinct t.* from table t group by t.id</select>5、jsp頁面引入<c:import url="/page/page.jsp"
3、;/>java代碼分頁信息實體/* * 分頁信息 */public class PageBean private int DEF_PAGE_VIEW_SIZE = 15; /* 當前頁 */ private int pageNo = 1; /* 當前頁顯示記錄條數 */ private int pageSize; /* 取得查詢總記錄數 */ private int totalRecord; /* 總頁數 */ private int totalPage; private String actionUrl; private Map<String, String> params
4、; public String getActionUrl() return actionUrl; public void setActionUrl(String actionUrl) this.actionUrl = actionUrl; public Map<String, String> getParams() return params; public void setParams(Map<String, String> params) this.params = params; /* * (空) */ public PageBean() this.pageNo
5、= 1; this.pageSize = DEF_PAGE_VIEW_SIZE; /* * 根據當前顯示頁與每頁顯示記錄數設置查詢信息初始對象 * * param pageNo 當前顯示頁號 * param pageSize 當前頁顯示記錄條數 */ public PageBean(int pageNo, int pageSize) this.pageNo = (pageNo <= 0) ? 1 : pageNo; this.pageSize = (pageSize <= 0) ? DEF_PAGE_VIEW_SIZE : pageSize; /* * 取得當前顯示頁號 * * r
6、eturn 當前顯示頁號 */ public int getPageNo() return (pageNo <= 0) ? 1 : pageNo; /* * 設置當前頁 * * param pageNo 當前頁 */ public void setPageNo(int pageNo) this.pageNo = pageNo; /* * 取得當前顯示頁號最多顯示條數 * * return 當前顯示頁號最多顯示條數 */ public int getPageSize() return (pageSize <= 0) ? DEF_PAGE_VIEW_SIZE : pageSize; /
7、* * 設置當前頁顯示記錄條數 * * param pageSize 當前頁顯示記錄條數 */ public void setPageSize(int pageSize) this.pageSize = pageSize; public int getTotalRecord() return totalRecord; public void setTotalRecord(int totalRecord) this.totalRecord = totalRecord; / 在設置總頁數的時候計算出對應的總頁數,在下面的三目運算中加法擁有更高的優(yōu)先級,所以最后可以不加括號。 int totalPa
8、ge = totalRecord % pageSize = 0 ? totalRecord / pageSize : totalRecord / pageSize + 1; this.setTotalPage(totalPage); public int getTotalPage() return this.totalPage; public void setTotalPage(int totalPage) this.totalPage = totalPage; 分頁信息操作幫助類,用于貫穿單次請求的各個層級/* * PageBean操作幫助類 */public class PageBeanU
9、tils / 定義一個當前線程對象,處于該主線程內的所有類均可調用該對象中的pagebean public static ThreadLocal<PageBean> local = new ThreadLocal<PageBean>(); public static PageBean getPageBean() PageBean pageBean = local.get(); if (pageBean = null) pageBean = new PageBean(); return pageBean; public static void setPageBean(Pa
10、geBean pageBean) local.set(pageBean); Controller攔截器,用于在執(zhí)行前后封裝或獲取分頁信息import com.xx.xx.util.StringUtils;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.Ht
11、tpServletResponse;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;/* * 分頁自動封裝攔截,在controller執(zhí)行前后對PageBean進行讀取和設置 */public class PageSpringMVCInterceptor extends HandlerInterceptorAdapter /* * preHandle方法是進行處理器攔截用的,顧名思義,該方法將在Controller處理之前進行調用,SpringMVC中的Interceptor攔截器是鏈式的,可
12、以同時存在 * 多個Interceptor,然后SpringMVC會根據聲明的前后順序一個接一個的執(zhí)行,而且所有的Interceptor中的preHandle方法都會在 * Controller方法調用之前調用。SpringMVC的這種Interceptor鏈式結構也是可以進行中斷的,這種中斷方式是令preHandle的返 * 回值為false,當preHandle的返回值為false的時候整個請求就結束了。 */ Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response
13、, Object handler) PageBean pageBean = new PageBean(); / 進入Controller前封裝page String pageNo = request.getParameter("pageNo"); String pageSize = request.getParameter("pageSize"); if (StringUtils.isNotEmpty(pageNo) pageBean.setPageNo(Integer.parseInt(pageNo); if (StringUtils.isNotEmp
14、ty(pageSize) pageBean.setPageSize(Integer.parseInt(pageSize); String url = request.getRequestURI(); Enumeration enumeration = request.getParameterNames(); / 綁定action地址 pageBean.setActionUrl(url); Map<String,String> params = new HashMap<String, String>(); while (enumeration.hasMoreElement
15、s() Object obj = enumeration.nextElement(); if (obj instanceof String) String paraname = String.valueOf(obj); try / 過濾掉頁面標簽 if (pageBean.getClass().getDeclaredField(paraname) != null) continue; catch (NoSuchFieldException e) String paraValue = request.getParameter(paraname); params.put(paraname, par
16、aValue); / 綁定參數 pageBean.setParams(params); PageBeanUtils.setPageBean(pageBean); return true; /* * 這個方法只會在當前這個Interceptor的preHandle方法返回值為true的時候才會執(zhí)行。postHandle是進行處理器攔截用的,它的執(zhí)行時間是在處理器進行處理之 * 后,也就是在Controller的方法調用之后執(zhí)行,但是它會在DispatcherServlet進行視圖的渲染之前執(zhí)行,也就是說在這個方法中你可以對ModelAndView進行操 * 作。這個方法的鏈式結構跟正常訪問的方向
17、是相反的,也就是說先聲明的Interceptor攔截器該方法反而會后調用,這跟Struts2里面的攔截器的執(zhí)行過程有點像, * 只是Struts2里面的intercept方法中要手動的調用ActionInvocation的invoke方法 * ,Struts2中調用ActionInvocation的invoke方法就是調用下一個Interceptor * 或者是調用action,然后要在Interceptor之前調用的內容都寫在調用invoke之前,要在Interceptor之后調用的內容都寫在調用invoke方法之后。 */ Override public void postHandle(H
18、ttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception /* * 不支持AJAX請求 */ PageBean pageBean = PageBeanUtils.getPageBean(); String requestType = request.getHeader("X-Requested-With"); if (requestType != null && requestType
19、.length() > 0 && requestType.equals("XMLHttpRequest") else request.setAttribute("_pageBean", pageBean); /* * 該方法也是需要當前對應的Interceptor的preHandle方法的返回值為true時才會執(zhí)行。該方法將在整個請求完成之后,也就是DispatcherServlet渲染了視圖執(zhí)行, * 這個方法的主要作用是用于清理資源的,當然這個方法也只能在當前這個Interceptor的preHandle方法的返回值為true時
20、才會執(zhí)行。 */ Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception Mybatis分頁攔截器,用于在執(zhí)行查詢時的分頁處理import mon.ReflectionUtils;import org.apache.ibatis.executor.parameter.ParameterHandler;import org.apache.ibatis.executor.s
21、tatement.RoutingStatementHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.*;import org.apache.ibatis.session.Configuration;import java.sql.Connection;import
22、java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;Intercepts(Signature(type = StatementHandler.class, method = "prepare", args = Connection.class)/* * mybatis分頁攔截器 所有以ForPage結尾的查詢方法,獲取分頁條件并動態(tài)添加分頁 */public class PageStatementHandle
23、rInterceptor implements Interceptor /* * 分頁攔截器。 * <p> * 功能主要是用來取總記錄數和對SQL分頁攔截。 * * param invocation * return * throws Throwable */ public Object intercept(Invocation invocation) throws Throwable RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget(); / 通過反射獲取到當前Rout
24、ingStatementHandler對象的delegate屬性 StatementHandler delegate = (StatementHandler) ReflectionUtils.getFieldValue(handler, "delegate"); / 通過反射獲取delegate父類BaseStatementHandler的mappedStatement屬性 MappedStatement mappedStatement = (MappedStatement) ReflectionUtils.getFieldValue(delegate, "map
25、pedStatement"); if (mappedStatement != null) / 獲取方法名,如果方法是以PAGE結尾的,則加工sql語句,添加分頁 String id = mappedStatement.getId(); if (id.toUpperCase().endsWith("FORPAGE") / 獲取sql綁定對象 BoundSql boundSql = delegate.getBoundSql(); / 拿到當前綁定Sql的參數對象,就是我們在調用對應的Mapper映射語句時所傳入的參數對象parameterType PageBean p
26、ageBean = PageBeanUtils.getPageBean(); / 獲取當前要執(zhí)行的Sql語句,也就是我們直接在Mapper映射語句中寫的Sql語句 String sql = boundSql.getSql(); / 給當前的page參數對象設置總記錄數 this.setTotalRecord(mappedStatement, boundSql, pageBean, (Connection) invocation.getArgs()0); / 獲取分頁Sql語句 String pageSql = this.getPageSql(pageBean, sql); / 利用反射設置當前
27、BoundSql對應的sql屬性為我們建立好的分頁Sql語句 ReflectionUtils.setFieldValue(boundSql, "sql", pageSql); return ceed(); /* * 攔截器對應的封裝原始對象的方法 */ public Object plugin(Object target) if (target instanceof StatementHandler) return Plugin.wrap(target, this); else return target; /* * 設置注冊攔截器時設定的屬性
28、* * param properties */ public void setProperties(Properties properties) /* * 根據page對象獲取對應的分頁查詢Sql語句,這里只做了兩種數據庫類型,Mysql和Oracle 其它的數據庫都 沒有進行分頁 * * param page 分頁對象 * param sql 原sql語句 * return */ private String getPageSql(PageBean page, String sql) StringBuffer sqlBuffer = new StringBuffer(sql); return
29、 getMysqlPageSql(page, sqlBuffer); /* * 獲取Mysql數據庫的分頁查詢語句 * * param page 分頁對象 * param sqlBuffer 包含原sql語句的StringBuffer對象 * return Mysql數據庫分頁語句 */ private String getMysqlPageSql(PageBean page, StringBuffer sqlBuffer) / 計算第一條記錄的位置,Mysql中記錄的位置是從0開始的。 int offset = (page.getPageNo() - 1) * page.getPageSiz
30、e(); sqlBuffer.append(" limit ").append(offset).append(",").append(page.getPageSize(); return sqlBuffer.toString(); /* * 給當前的參數對象page設置總記錄數 */ private void setTotalRecord(MappedStatement mappedStatement, BoundSql boundSql, PageBean pageBean, Connection connection) String sql = bo
31、undSql.getSql(); String countSql = getCountSql(sql.trim(); PreparedStatement countStmt = null; ResultSet rs = null; try countStmt = connection.prepareStatement(countSql); / 向countStmt中傳遞參數 Configuration configuration = mappedStatement.getConfiguration(); ParameterHandler handler = configuration.newP
32、arameterHandler(mappedStatement, boundSql.getParameterObject(), boundSql); handler.setParameters(countStmt); rs = countStmt.executeQuery(); int totalCount = 0; if (rs.next() totalCount = rs.getInt(1); pageBean.setTotalRecord(totalCount); PageBeanUtils.setPageBean(pageBean); catch (Exception e) e.pri
33、ntStackTrace(); finally try if (rs != null) rs.close(); if (countStmt != null) countStmt.close(); / connection.close(); catch (SQLException e) e.printStackTrace(); /* * 根據原Sql語句獲取對應的查詢總記錄數的Sql語句 * * param sql * return */ private String getCountSql(String sql) return "select count(1) from ("
34、; + sql + ") t_page_count_sql" 參數獲取幫助類public class ReflectionUtils public ReflectionUtils() public static Object getFieldValue(Object obj, String fieldName) Object result = null; Field field = getField(obj, fieldName); if(field != null) field.setAccessible(true); try result = field.get(obj
35、); catch (IllegalArgumentException var5) var5.printStackTrace(); catch (IllegalAccessException var6) var6.printStackTrace(); return result; private static Field getField(Object obj, String fieldName) Field field = null; Class clazz = obj.getClass(); while(clazz != Object.class) try field = clazz.get
36、DeclaredField(fieldName); break; catch (NoSuchFieldException var5) clazz = clazz.getSuperclass(); return field; public static void setFieldValue(Object obj, String fieldName, String fieldValue) Field field = getField(obj, fieldName); if(field != null) try field.setAccessible(true); field.set(obj, fi
37、eldValue); catch (IllegalArgumentException var5) var5.printStackTrace(); catch (IllegalAccessException var6) var6.printStackTrace(); public static void invoke(Object obj, String methodName, Object arg) throws Exception BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(); MethodDescriptor met
38、hodDescriptors = beanInfo.getMethodDescriptors(); MethodDescriptor arr$ = methodDescriptors; int len$ = methodDescriptors.length; for(int i$ = 0; i$ < len$; +i$) MethodDescriptor md = arr$i$; if(md.getName().equals(methodName) md.getMethod().invoke(obj, new Objectarg); 配置文件Spring配置信息<?xml vers
39、ion="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xmlns:mvc="/schema/mvc" xmlns:aop="/schema
40、/aop" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-3.2.xsd /schema/aop /schema/aop/spring-aop-3.2.xsd /schema/mvc http:/www.sprin
41、/schema/mvc/spring-mvc-3.2.xsd" default-lazy-init="true"> <!-如在項目中已經配置了mvc:interceptors ,為了避免沖突,請將以下mvc:interceptors內容配置在一起-> <mvc:interceptors> <mvc:interceptor> <!-<!–設置攔截的路徑–>-> <mvc:mapping path="/*
42、"/> <bean class="erceptor.PageSpringMVCInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> <!-分頁封裝-> <bean id="pageStatementHandlerInterceptor" class="erceptor.PageStatementHandlerInterceptor"> <proper
43、ty name="properties"> <value> </value> </property> </bean> <!- MyBatis配置 平臺 begin-> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!- 分頁攔截器 -> <property name="plugins"> <lis
44、t> <ref bean="pageStatementHandlerInterceptor"/> </list> </property><!-以下內容為項目自帶,請根據自身需要修改-> <property name="dataSource" ref="dataSource"/> <!- 自動掃描entity目錄, 省掉Configuration.xml里的手工配置,多個目錄用,分隔 -> <property name="typeAliases
45、Package" value="com.xx.xx.xx.entity"/> <!- 顯式指定Mapper文件位置 -> <property name="mapperLocations" value="classpath:/mybatis/*/*Mapper.xml"/></bean><!-以下內容為項目自帶,請根據自身需要修改-> <!- 掃描basePackage下所有以MyBatisRepository標識的 接口-> <bean id="
46、;baseMapperConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!- 多個dao包用,分隔-> <property name="basePackage" value="com.xx.xx.edc.dao.*"/
47、> <property name="annotationClass" value="mon.MyBatisRepository"/> </bean> <!- MyBatis配置 平臺 end-></beans>Jsp頁面樣式page.css/*翻頁樣式*/.page float: right; margin: 10px 0; height: 28px; line-height: 28px;.page a, .page a:link, .page a:visited width: 28px; height: 27px; border: 1px solid #e1e1e1; text-align: center; line-height: 28px; margin-right: 10px; float: left; display: block; text-decoration: none; color: #666;.page a:hover background: #def2ff;.p
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版綠色建筑施工現場環(huán)保設施租賃合同2篇
- 2025年林業(yè)重點工程項目樹木種植承包合同范本3篇
- 2025年水上運輸船舶檢驗與認證合同3篇
- 2025年度大連建筑工程施工合同施工場地占用協(xié)議3篇
- 二零二五版砍樹承包合同聯(lián)合森林碳匯交易協(xié)議2篇
- 二零二五版大豆期貨交易委托合同樣本2篇
- 二零二四上海離婚協(xié)議書定制與婚姻法律風險評估、咨詢、代理、調解及訴訟服務合同3篇
- 2024新借款合同范本
- 2025年度綠色屋頂綠化租賃項目合同4篇
- 二零二五年度玻璃幕墻保溫隔熱材料供應合同樣本3篇
- 充電樁項目運營方案
- 2024年農民職業(yè)農業(yè)素質技能考試題庫(附含答案)
- 高考對聯(lián)題(對聯(lián)知識、高考真題及答案、對應練習題)
- 新版《鐵道概論》考試復習試題庫(含答案)
- 【律師承辦案件費用清單】(計時收費)模板
- 高中物理競賽真題分類匯編 4 光學 (學生版+解析版50題)
- Unit1FestivalsandCelebrations詞匯清單高中英語人教版
- 西方經濟學-高鴻業(yè)-筆記
- 2024年上海市中考語文試題卷(含答案)
- 幼兒園美術教育研究策略國內外
- 生豬養(yǎng)殖生產過程信息化與數字化管理
評論
0/150
提交評論