您好,登錄后才能下訂單哦!
這篇文章給大家介紹基于Struts2和Freemarkeri的Batis分頁是怎么樣的,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
之前介紹過基于Hibernate分頁的原理和設計,這里我們所用的分頁都是物理分頁技術,不是JS實現的頁面分頁技術,是在SQL語句上執行的分頁,可以獲取結果集數量固定的列表,執行效率很高。下面來看看iBatis中如何設計分頁,本文基于Struts2,Spring3來整合,因為暫時Spring不支持MyBatis3(可以選用MyBatis官方的MyBatis-Spring插件來實現,配有中文文檔,很好理解),我們這里仍然以iBatis2作為載體來介紹。
首先就是搭建開發環境,這里可以說也是對Struts2,Spring3和iBatis2進行了簡單的整合,大家也可以來參考。項目的結構如下,使用Maven創建的web項目:
添加必要的依賴,因為整合了Struts2和Spring,依賴就比較多了,如下:
首先來配置一下Struts2,這個就比較簡單了,相信大家都不陌生。在web.xml中:
Xml代碼
<filter> <filter-name>struts2filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterfilter-class> filter> <filter-mapping> <filter-name>struts2filter-name> <url-pattern>*.actionurl-pattern> filter-mapping>
然后是struts.xml,配置Struts相關的內容,這里我們配置freemarker為默認的結果類型,然后配置一個測試的Action,因為和Spring進行了集成,所以Action具體的配置放到Spring中來進行,如下即可:
Xml代碼
<?xml version="1.0" encoding="UTF-8" ?> "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="ibatis-paging" extends="struts-default" namespace="/"> <result-types> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult" default="true" /> result-types> <action name="user_*" class="userAction" method="{1}"> <result name="list">user_list.ftlresult> action> package> struts>
對Freemarker做一個簡單的設置,卸載freeemarer.properties文件中即可,這里我們主要是引用了一個宏文件,就是分頁宏的配置,如下:
Properties代碼
template_update_delay=5 default_encoding=UTF-8 url_escaping_charset=UTF-8 number_format=0.# date_format=yyyy-MM-dd time_format=HH:mm:ss datetime_format=yyyy-MM-dd HH:mm:ss boolean_format=true,false whitespace_stripping=true tag_syntax=auto_detect auto_import=/Freemarker/page_macro.ftl as p
Log4J的配置這里不再貼出代碼,大家可以去下載源碼,一看就明白了,之后我們配置Spring,在resources文件夾下創建spring子目錄,里面放置Spring的配置文件,在web.xml中如下設置即可加載Spring的配置文件:
Xml代碼
<context-param> <param-name>contextConfigLocationparam-name> <param-value>classpath:spring/*.xmlparam-value> context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class> listener>
Spring中主要配置數據源,iBatis的SqlMapClient和SqlMapClientTemplate,事務處理還有Action和Service的管理,其實內容大家也都很熟悉了,比較簡單:
Xml代碼
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="123" /> <property name="maxActive" value="100" /> <property name="maxIdle" value="50" /> <property name="maxWait" value="100" /> <property name="defaultAutoCommit" value="true" /> bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:sqlMapConfig.xml" /> <property name="dataSource" ref="dataSource" /> bean> <bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <constructor-arg> <ref bean="sqlMapClient" /> constructor-arg> bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> bean> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="add*" rollback-for="Exception" /> <tx:method name="addOrUpdate*" rollback-for="Exception" /> <tx:method name="del*" rollback-for="Exception" /> <tx:method name="update*" rollback-for="Exception" /> tx:attributes> tx:advice> <aop:config proxy-target-class="true"> <aop:pointcut id="serviceMethod" expression="execution(* org.ourpioneer.service.*Service.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" /> aop:config>
之后對Service和Action進行配置:
Xml代碼
<bean id="userService" class="org.ourpioneer.service.UserService"> <property name="sqlMapClientTemplate" ref="sqlMapClientTemplate" /> bean> <bean id="userAction" class="org.ourpioneer.action.UserAction"> <property name="userService" ref="userService" /> bean>
下面來看一下iBatis的配置,在配置SqlMapClient的時候,加入了iBatis的配置文件,我們來看看sqlMapConfig.xml如何來設置:
Xml代碼
<?xml version="1.0" encoding="UTF-8" ?> PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" errorTracingEnabled="true" maxRequests="32" maxSessions="10" maxTransactions="5" /> <sqlMap resource="sqlMaps/user.xml" /> sqlMapConfig>
其實內容也很簡單,就是設置一下必要的信息,其中的含義可以參考之前寫過的對iBatis的介紹的相關文章,最后不要忘了加入sqlMaps配置文件即可,這里我們就一個user.xml文件,為了測試,也就是一條查詢,針對這個查詢進行分頁操作:
Xml代碼
<?xml version="1.0" encoding="UTF-8" ?> > <sqlMap> <typeAlias alias="parameterMap" type="org.pioneer.bean.ParameterMap" /> <select id="selectAllUsers" resultClass="java.util.HashMap"> select * from user select> sqlMap>
ParameterMap在之前的介紹中也多次出現,這里我們也再來看下:
Java代碼
package org.ourpioneer.bean; import java.util.HashMap; public class ParameterMap extends HashMap { public ParameterMap(Object... parameters) { for (int i = 0; i < parameters.length - 1; i += 2) { super.put(parameters[i], parameters[i + 1]); } } }
其實就是擴展了一下HashMap類,來進行參數的放置,注意參數類型是可變參數的形式,也就是名-值對的形式出現的,不過本例中沒有使用它。下面就是分頁類的設計了:
Java代碼
package org.ourpioneer.bean; import java.util.List; import org.springframework.orm.ibatis.SqlMapClientTemplate; /** * iBatis分頁類 * * @author Nanlei * */ public class PagingList { private int rowCount = 0; // 記錄總數 private int pageCount = 1; // 分頁總數 private int pageSize = 10; // 每頁記錄數 private int pageNum = 1; // 當前頁數 private int startIndex = 1; // 起始記錄數 private int endIndex = 1; // 結束記錄數 private List list;// 記錄列表 /** * 構造方法,進行分頁 * * @param statementName * iBatis中語句的ID * @param parameterObject * SQL語句參數 * @param pageNum * 起始頁數 * @param pageSize * 每頁大小 * @param sqlMapClientTemplate * iBatis的sqlMapClientTemplate對象 */ public PagingList(String statementName, Object parameterObject, int pageNum, int pageSize, SqlMapClientTemplate sqlMapClientTemplate) { preProcessParams(pageNum, pageSize); execute(statementName, parameterObject, pageNum, pageSize, sqlMapClientTemplate); } /** * 構造方法,進行分頁 * * @param statementName * iBatis中語句的ID * @param pageNum * 起始頁數 * @param pageSize * 每頁大小 * @param sqlMapClientTemplate * iBatis的sqlMapClientTemplate對象 */ public PagingList(String statementName, int pageNum, int pageSize, SqlMapClientTemplate sqlMapClientTemplate) { preProcessParams(pageNum, pageSize); execute(statementName, pageNum, pageSize, sqlMapClientTemplate); } /** * 執行方法 * * @param statementName * @param parameterObject * @param pageNum * @param pageSize * @param sqlMapClientTemplate */ blic void execute(String statementName, Object parameterObject, int pageNum, int pageSize, SqlMapClientTemplate sqlMapClientTemplate) { // 計算記錄總數 this.rowCount = sqlMapClientTemplate.queryForList(statementName, parameterObject).size(); // 計算分頁數及起止記錄 countPage(); // 獲取分頁列表 this.list = sqlMapClientTemplate.queryForList(statementName, parameterObject, (pageNum - 1) * pageSize, pageSize); } /** * 執行方法 * * @param statementName * @param pageNum * @param pageSize * @param sqlMapClientTemplate */ public void execute(String statementName, int pageNum, int pageSize, SqlMapClientTemplate sqlMapClientTemplate) { // 計算記錄總數 this.rowCount = sqlMapClientTemplate.queryForList(statementName).size(); // 計算分頁數及起止記錄 countPage(); // 獲取分頁列表 this.list = sqlMapClientTemplate.queryForList(statementName, (pageNum - 1) * pageSize, pageSize); } /** * 預處理SQL語句和頁面參數 */ private void preProcessParams(int pageNum, int pageSize) { if (pageNum > 0) { this.pageNum = pageNum; } if (pageSize > 0) { this.pageSize = pageSize; } if (pageSize > 1000) { this.pageSize = 1000; } } /** * 計算分頁數及起止記錄 */ private void countPage() { // 計算分頁總數 if ((rowCount % pageSize) == 0) { pageCount = rowCount / pageSize; } else { pageCount = rowCount / pageSize + 1; } if (pageCount == 0) { pageCount = 1; } // 判斷pageNum是否過界 if (pageNum > pageCount && rowCount != 0) { pageNum = pageCount; } // 計算起止記錄 startIndex = (pageNum - 1) * pageSize + 1; endIndex = (pageNum) * pageSize; } /** * 獲得對象列表 */ public List getList() { return list; } /* 獲得起始記錄數 */ public int getStartIndex() { return startIndex; } public Integer getStartIndexInteger() { return new Integer(startIndex); } /* 獲得結束記錄數 */ public int getEndIndex() { return endIndex; } public Integer getEndIndexInteger() { return new Integer(endIndex); } /* 獲得分頁其它信息 */ public int getPageCount() { return pageCount; } public int getPageNum() { return pageNum; } public int getPageSize() { return pageSize; } public int getRowCount() { return rowCount; } }
寫好分頁類,還要和框架進行集成,那么我們可以抽象出Service的基類,在業務邏輯層中調用它來獲取分頁信息:
Java代碼
package org.ourpioneer.service; import org.ourpioneer.bean.PagingList; import org.springframework.orm.ibatis.SqlMapClientTemplate; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.util.ValueStack; public class BaseService { /** * 獲取ValueStack * * @return ValueStack對象 */ public ValueStack getValueStack() { return ActionContext.getContext().getValueStack(); } /** * 獲取分頁的List * * @param statementName * @param sqlMapClientTemplate * @return */ public PagingList getPagingList(String statementName, SqlMapClientTemplate sqlMapClientTemplate) { int pageNum = ((Integer) getValueStack().findValue("pageNum")) .intValue(); int pageSize = ((Integer) getValueStack().findValue("pageSize")) .intValue(); return new PagingList(statementName, pageNum, pageSize, sqlMapClientTemplate); } /** * 獲取分頁的List * * @param statementName * @param parameterObject * @param sqlMapClientTemplate * @return */ public PagingList getPagingList(String statementName, Object parameterObject, SqlMapClientTemplate sqlMapClientTemplate) { int pageNum = ((Integer) getValueStack().findValue("pageNum")) .intValue(); int pageSize = ((Integer) getValueStack().findValue("pageSize")) .intValue(); return new PagingList(statementName, parameterObject, pageNum, pageSize, sqlMapClientTemplate); } }
兩個構造方法我們都使用了,也就是一個帶參數,一個不帶參數。下面來看抽象出的Action基類,主要是處理頁面傳入的分頁參數的處理:
Java代碼
package org.ourpioneer.action; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import org.ourpioneer.util.QueryUtil; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class BaseAction extends ActionSupport { @Override public String execute() throws Exception { return SUCCESS; } public Map getParameters() { return ActionContext.getContext().getParameters(); } public HttpServletRequest getRequest() { return ServletActionContext.getRequest(); } /* 分頁信息 */ protected int pageNum = 1; protected int pageSize = 10; public int getPageNum() { return pageNum; } public void setPageNum(int pageNum) { this.pageNum = pageNum; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getMaxPageSize() { return 1000; } public int getDefaultPageSize() { return 10; } // 頁面解析分頁信息使用的方法 public String getQueryStringWithoutPageNum() { Map m = getParameters(); m.remove("pageNum"); return QueryUtil.getQueryString(m); } public String getFullUrlWithoutPageNum() { return getRequest().getServletPath() + "?" + getQueryStringWithoutPageNum(); } public String getQueryStringWithoutPageInfo() { Map m = getParameters(); m.remove("pageNum"); m.remove("pageSize"); return QueryUtil.getQueryString(m); } public String getFullUrlWithoutPageInfo() { return getRequest().getServletPath() + "?" + getQueryStringWithoutPageInfo(); } }
這里為了演示,我們將分頁的信息都直接定義死了,大家可以根據需要來修改,其中處理信息的QueryUtil大家可以直接參考源代碼,這里不做說明了,下面是UserAction處理代碼的編寫:
Java代碼
package org.ourpioneer.action; import org.ourpioneer.bean.PagingList; import org.ourpioneer.service.UserService; public class UserAction extends BaseAction { private UserService userService; public PagingList userList; public void setUserService(UserService userService) { this.userService = userService; } public PagingList getUserList() { return userList; } public String list() { userList = userService.getAllUsers(); return "list"; } }
根據前面的配置,我們也不難寫出代碼,下面就是視圖處理了,我們使用了Freemarker進行解析,也編寫了FreeMarker的分頁宏:
Html代碼
<#-- 處理分頁參數 --> <#function getPageUrl pageNum> <#local pageUrl=base+fullUrlWithoutPageInfo> <#if pageUrl?ends_with("?")> <#return pageUrl + "pageSize=" + pageSize + "&pageNum=" + pageNum> <#else> <#return pageUrl + "&pageSize=" + pageSize + "&pageNum=" + pageNum> #if> #function> <#-- 全部或分頁顯示 --> <#function getPageUrlResize size> <#local pageUrl=base+fullUrlWithoutPageInfo> <#if pageUrl?ends_with("?")> <#return pageUrl + "pageNum=1&pageSize=" + size> <#else> <#return pageUrl + "&pageNum=1&pageSize=" + size> #if> #function> <#-- 分頁信息 --> <#macro paging pagingList> <#local pageCount=pagingList.pageCount> <#local rowCount=pagingList.rowCount> <#local pageNum=pagingList.pageNum> <#local pageSize=pagingList.pageSize> <#if rowCount == 0> <#if useFlag?exists> <div style="border:1px solid #666;padding:2 5 2 5;background:#efefef;color:#333">沒有相關記錄div> <#else> <#assign useFlag = 1> #if> <#else> <table> <tr> <td style="line-height:150%">共 ${rowCount} 條記錄 ${pageCount} 頁 <#if pageCount gt 1 && pageSize!=maxPageSize> <span class="selectedPage" style="padding:2px 3px 0 3px"><a class="page" href="${getPageUrlResize(maxPageSize)}">全部顯示a>span> <#elseif pageSize==maxPageSize> <span class="selectedPage" style="padding:2px 3px 0 3px"><a class="page" href="${getPageUrlResize(defaultPageSize)}">分頁顯示a>span> #if> <#if (pageCount <= 11)> <#local startPage = 1> <#local endPage = pageCount> <#elseif (pageNum + 5 > pageCount)> <#local startPage = pageCount - 10> <#local endPage = pageCount> <#elseif (pageNum - 5 < 1)> <#local startPage = 1> <#local endPage = 11> <#else> <#local startPage = pageNum - 5> <#local endPage = pageNum + 5> #if> <#if (pageCount > 1)> <#if (pageNum != 1)> <#if (pageCount > 11)> <a class="page" href="${getPageUrl(1)}" style="font-family:Webdings" title="首頁">9a> #if> <a class="page" href="${getPageUrl(pageNum-1)}" style="font-family:Webdings" title="上頁">3a> <#else> <#if (pageCount > 11)> <span style="font-family:Webdings;color:#999">9span> #if> <span style="font-family:Webdings;color:#999">3span> #if> <#list startPage..endPage as x> <#if x=pageNum> <span class="selectedPage">${x}span> <#else> <span class="noSelectedPage"><a class="page" href="${getPageUrl(x)}">${x}a>span> #if> #list> <#if (pageCount != pageNum)> <a class="page" href="${getPageUrl(pageNum+1)}" style="font-family:Webdings" title="下頁">4a> <#if (pageCount > 11)> <a class="page" href="${getPageUrl(pageCount)}" style="font-family:Webdings" title="尾頁">:a> #if> <#else> <span style="font-family:Webdings;color:#999">4span> <#if (pageCount > 11)> <span style="font-family:Webdings;color:#999">:span> #if> #if> #if> td> tr> table> #if> #macro>
之后,我們來運行項目:
可以通過點擊全部顯示和頁面來查看分頁效果。
關于基于Struts2和Freemarkeri的Batis分頁是怎么樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。