這篇文章給大家介紹基于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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。