步驟:default.properties(放到src目錄下)àConfiguration.java(放到cn.itcast.cfg包下)àPageBeanàActionàServicejavascript
default.properties:css
pageSize=10html |
Configuration.java:java
package cn.itcast.cfg; spring /** sql * 管理配置信息(讀取配置文件)數據庫 * @author Tan 數組 * session */ app public class Configuration {
private static int pageSize = 10;
static{ //加載default.properties配置文件 //... }
public static int getPageSize() { return pageSize; } public static void setPageSize(int pageSize) { Configuration.pageSize = pageSize; } } |
package cn.itcast.oa.domain; import java.util.List;
/** * 分頁用的一頁的信息對象 * @author Tan * */ public class PageBean { //傳遞的參數或配置的值 private int currentPage; //當前頁 private int pageSize; //每頁顯示的記錄數 //查詢數據庫 private int recordCount; //總記錄數 private List recordList; //本頁的數據列表 //計算出來的 private int pageCount; //總頁數 private int beginPageIndex; //頁面列表的開始索引 private int endPageIndex; //頁面列表的結束索引
/** * 只接受前四個屬性的值,會自動計算後四個屬性的值 * @param currentPage * @param pageSize * @param recordCount * @param recordList */ public PageBean(int currentPage, int pageSize, int recordCount, List recordList) { this.currentPage = currentPage; this.pageSize = pageSize; this.recordCount = recordCount; this.recordList = recordList;
//計算pageCount總頁數 pageCount = (recordCount + pageSize - 1)/ pageSize;
//計算beginPageIndex和endPageIndex //a.若是總頁數不超過十頁,就所有顯示 if(pageCount <= 10){ beginPageIndex = 1; endPageIndex = pageCount; //b.若是總頁數超過十頁,就顯示當前頁附近的共10個頁碼,(前4頁+當前頁+後5頁) }else{ //就顯示當前頁附近的共10個頁碼,(前4頁+當前頁+後5頁) beginPageIndex = currentPage - 4; endPageIndex = currentPage + 5;
//若是前面不足4個頁碼,就顯示前10頁 if(beginPageIndex < 1){ beginPageIndex = 1; endPageIndex = 10;
//若是後面不足5個頁碼,就顯示後10頁 }else if(endPageIndex > pageCount){ endPageIndex = pageCount; beginPageIndex = pageCount - 10 + 1; //注意:在顯示的時候是包含兩個邊界的 } } } (此處省略他們的get/set方法) } |
修改FroumAction:
@Controller @Scope("prototype") public class ForumAction extends BaseAction<Forum>{
private int pageNum = 1; //當前頁,默認爲第一頁
/** 版塊列表 */ public String list() throws Exception { List<Forum> forumList = forumService.findAll(); ActionContext.getContext().put("forumList", forumList); return "list"; }
/** 顯示單個版塊(主題列表) */ public String show() throws Exception { //準備數據:forum Forum forum = forumService.getById(model.getId()); ActionContext.getContext().put("forum", forum);
/*//準備數據:topicList List<Topic> topicList = topicService.findByForum(forum); ActionContext.getContext().put("topicList", topicList);*/
//準備分頁的數據 PageBean pageBean = topicService.getPageBeanByForum(pageNum, forum); ActionContext.getContext().getValueStack().push(pageBean);
return "show"; } //------------ public int getPageNum() { return pageNum; }
public void setPageNum(int pageNum) { this.pageNum = pageNum; } } |
Tips:由於pageSize已經在配置文件中指出,而配置文件中的數據在哪都能被取出來,在業務層取出pageSize比較好,因此在action中只接收當前頁.
TopicServiceImpl:
@Service @Transactional @SuppressWarnings("unchecked") public class TopicServiceImpl extends DaoSupportImpl<Topic> implements TopicService{
/** * 查詢指定版塊的主題列表,最新狀態的排到前面,置頂帖排到最前面 */ public List<Topic> findByForum(Forum forum) { return getSession().createQuery(// "from Topic t where t.forum = ? order by (case t.type when 2 then 2 else 0 end) desc, t.lastUpdateTime desc")// .setParameter(0, forum)// .list(); }
/** * 重寫save() */ public void save(Topic topic) { //設置屬性並保存 topic.setType(topic.TYPE_NORMAL); //普通帖 topic.setReplyCount(0); topic.setLastReply(null); topic.setPostTime(new Date()); //當前時間 topic.setLastUpdateTime(topic.getPostTime()); //默認爲主題的發表時間
getSession().save(topic);
//更新相關信息 Forum forum = topic.getForum(); forum.setTopicCount(forum.getTopicCount()+1); //主題數量 forum.setArticleCount(forum.getArticleCount()+1); //回覆數量(主題+回覆) forum.setLastTopic(topic); //最後發表主題
getSession().update(forum); }
/** * 查詢分頁的主題列表數據 */ public PageBean getPageBeanByForum(int pageNum, Forum forum) { //獲取pageSize信息 int pageSize = Configuration.getPageSize();
//查詢一頁的數據信息 List list = getSession().createQuery(// "from Topic t where t.forum = ? order by (case t.type when 2 then 2 else 0 end) desc, t.lastUpdateTime desc")// .setParameter(0, forum)// .setFirstResult((pageNum - 1) * pageSize) //(當前頁pageNum - 1) * 每頁顯示的條數pageSize 意思是:從數據庫中的第幾條記錄開始查詢,下標是從0開始的,因此要先-1 .setMaxResults(pageSize) //每頁顯示的條數,即查詢數據庫中的多少條記錄 .list();
//查詢總記錄數 Long count = (Long)getSession().createQuery(// "select count(*) from Topic t where t.forum=?")// .setParameter(0, forum)// .uniqueResult();
return new PageBean(pageNum, pageSize, count.intValue(), list); } } |
ForumAction對應的show.jsp:
…… <!-- 標題顯示 --> <div id="Title_bar"> <div id="Title_bar_Head"> <div id="Title_Head"></div> <div id="Title"><!--頁面標題--> <img border="0" width="13" height="13" src="${pageContext.request.contextPath}/style/images/title_arrow.gif"/>【${forum.name }】中的主題列表 </div> <div id="Title_End"></div> </div> </div>
<div id="MainArea"> <div id="PageHead"></div> <center> <div class="ItemBlock_Title1" style="width: 98%;"> <font class="MenuPoint"> > </font> <s:a action="forum_list">論壇</s:a> <font class="MenuPoint"> > </font> ${forum.name } <span style="margin-left:30px;"><s:a action="topic_addUI?forumId=%{#forum.id }"> <img align="absmiddle" src="${pageContext.request.contextPath}/style/blue/images/button/publishNewTopic.png"/></s:a> </span> </div>
<div class="ForumPageTableBorder"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <!--表頭--> <tr align="center" valign="middle"> <td width="3" class="ForumPageTableTitleLeft"> <img border="0" width="1" height="1" src="${pageContext.request.contextPath}/style/images/blank.gif" /> </td> <td width="50" class="ForumPageTableTitle"><!--狀態/圖標--> </td> <td class="ForumPageTableTitle">主題</td> <td width="130" class="ForumPageTableTitle">做者</td> <td width="100" class="ForumPageTableTitle">回覆數</td> <td width="130" class="ForumPageTableTitle">最後回覆</td> <td width="3" class="ForumPageTableTitleRight"> <img border="0" width="1" height="1" src="${pageContext.request.contextPath}/style/images/blank.gif" /> </td> </tr> <tr height="1" class="ForumPageTableTitleLine"><td colspan="8"></td></tr> <tr height=3><td colspan=8></td></tr>
<!--主題列表--> <tbody class="dataContainer" datakey="topicList"> <s:iterator value="recordList"> <tr height="35" id="d0" class="template"> <td></td> <td class="ForumTopicPageDataLine" align="center"><img src="${pageContext.request.contextPath}/style/images/topicType_${type}.gif" /></td> <td class="Topic"><s:a cssClass="Default" action="topic_show?id=%{id}">${title}</s:a></td> <td class="ForumTopicPageDataLine"> <ul class="ForumPageTopicUl"> <li class="Author">${author.name}</li> <li class="CreateTime"><s:date name="postTime" format="yyyy年MM月dd日 HH:mm:ss"/> </li> </ul> </td> <td class="ForumTopicPageDataLine Reply" align="center"><b>${replyCount}</b></td> <td class="ForumTopicPageDataLine"> <ul class="ForumPageTopicUl"> <li class="Author">${lastReply.author.name }</li> <li class="CreateTime"><s:date name="lastReply.postTime" format="yyyy年MM月dd日 HH:mm:ss"/></li> </ul> </td> <td></td> </tr> </s:iterator> </tbody> <!--主題列表結束-->
<tr height="3"><td colspan="9"></td></tr>
</table> …… </div> </center> </div>
<!--分頁信息--> <div id=PageSelectorBar> <div id=PageSelectorMemo><!-- 由於action把pageBean push進了棧頂,因此前面不用加pageBean. --> 頁次:${currentPage}/${pageCount} 頁 每頁顯示:${pageSize}條 總記錄數:${recordCount}條 </div> <div id=PageSelectorSelectorArea> <a href="javascript: gotoPage(1)" title="首頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/></a>
<!-- 頁碼列表 --><!--%{beginPageIndex}這是ognl表達式,pageBean在棧頂, var="num",num被var放到了map域,因此取出num要加# --> <s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var="num"> <s:if test="#num != currentPage"><!-- 非當前頁,有連接 --> <span class="PageSelectorNum" style="cursor: hand;" onClick="gotoPage(${num});">${num }</span> </s:if> <s:else><!-- 當前頁,沒有連接 --> <span class="PageSelectorNum PageSelectorSelected">${num }</span> </s:else> </s:iterator>
<a href="javascript: gotoPage(${pageCount})" title="尾頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/></a>
轉到: <select id="pn" onchange="gotoPage(this.value)"> <s:iterator begin="1" end="%{pageCount}" var="num"> <option value="${num }">${num }</option> </s:iterator> </select>
<!-- 讓select默認選中當前頁 --> <script type="text/javascript"> $("#pn").val("${currentPage}"); </script>
<script type="text/javascript"> <!-- 轉到指定的頁碼 --> function gotoPage(pageNum){ window.location.href = "forum_show.do?id=${id}&pageNum="+pageNum; <!—-這裏將當前頁pageNum傳給了Action,action中用屬性驅動的方式接收--> } </script> </div> </div> ……. |
%{}這是OGNL表達式,${}這是EL表達式.傻傻分不清…
難道說,在配合s:iterator,s:select等struts2標籤使用的時候,一般用%{},普通標籤就用${}??????????
頁面效果:
轉到:如下拉選的形式展現全部頁碼,點擊頁碼,頁面就會立刻跳轉到相應頁碼.
順序依舊是:pageBeanèActionèserviceèjsp
這裏先把重複代碼抽取出來(暫時先抽取action中的少許代碼和jsp中的分頁代碼,service中的代碼後面再抽取)
將以前寫在ForumAction中的pageNum和其get,set方法抽取到BaseAction中:
//-----------對分頁的支持---------------- protected int pageNum = 1; //當前頁,默認爲第一頁 public int getPageNum() { return pageNum; }
public void setPageNum(int pageNum) { this.pageNum = pageNum; } |
再將jsp中的分頁代碼抽取到新建到public文件夾中新建的pageView.jspf:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <!--分頁信息--> <div id=PageSelectorBar> <div id=PageSelectorMemo> 頁次:${currentPage}/${pageCount} 頁 每頁顯示:${pageSize}條 總記錄數:${recordCount}條 </div> <div id=PageSelectorSelectorArea> <a href="javascript: gotoPage(1)" title="首頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/></a>
<!-- 頁碼列表 --> <s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var="num"> <s:if test="#num != currentPage"><!-- 非當前頁,有連接 --> <span class="PageSelectorNum" style="cursor: hand;" onClick="gotoPage(${num});">${num }</span> </s:if> <s:else><!-- 當前頁,沒有連接 --> <span class="PageSelectorNum PageSelectorSelected">${num }</span> </s:else> </s:iterator>
<a href="javascript: gotoPage(${pageCount})" title="尾頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/></a>
轉到: <select id="pn" onchange="gotoPage(this.value)"> <s:iterator begin="1" end="%{pageCount}" var="num"> <option value="${num }">${num }</option> </s:iterator> </select>
<!-- 讓select默認選中當前頁 --> <script type="text/javascript"> $("#pn").val("${currentPage}"); </script>
<!-- <script type="text/javascript"> <!-- 轉到指定的頁碼 --> <%-- function gotoPage(pageNum){ window.location.href = "forum_show.do?id=${id}&pageNum="+pageNum; } </script> --%> </div> </div> |
其中,最後一段代碼由於不一樣頁面要傳遞的id值也不一樣,因此不能做爲公共代碼.
TopicAction:
@Controller @Scope("prototype") public class TopicAction extends BaseAction<Topic>{
private Long forumId;
/** 顯示單個主題 */ public String show() throws Exception { //準備數據:topic Topic topic = topicService.getById(model.getId()); ActionContext.getContext().put("topic", topic);
/*//準備數據:replyList List<Reply> replyList = replyService.findByTopic(topic); ActionContext.getContext().put("replyList", replyList);*/
//準備數據 PageBean pageBean = replyService.getPageBeanByTopic(pageNum, topic); ActionContext.getContext().getValueStack().push(pageBean);
return "show"; }
/** 發新帖頁面*/ public String addUI() throws Exception { //準備數據:forum Forum forum = forumService.getById(forumId); ActionContext.getContext().put("forum", forum); return "addUI"; }
/** 發新帖 */ public String add() throws Exception { //封裝對象 Topic topic = new Topic(); //須要在action中封裝的數據: //>>a.表單中的參數 topic.setTitle(model.getTitle()); topic.setContent(model.getContent()); topic.setForum(forumService.getById(forumId)); //>>b.在顯示層才能得到的數據 topic.setAuthor(getCurrentUser()); //當前登陸的用戶 topic.setIpAddr(getRequestIp()); //客戶端的IP地址
//調用業務方法 topicService.save(topic);
ActionContext.getContext().put("topicId", topic.getId()); return "toShow"; //轉到當前這個新主題的頁面 }
//----------------------------------- public Long getForumId() { return forumId; }
public void setForumId(Long forumId) { this.forumId = forumId; } } |
ReplyServiceImpl:
@Service @Transactional public class ReplyServiceImpl extends DaoSupportImpl<Reply> implements ReplyService{
/** * 重寫save(),處理特殊屬性 */ public void save(Reply reply) { reply.setPostTime(new Date()); //發表時間爲當前時間 reply.setDeleted(false); //默認爲未刪除
getSession().save(reply); //處理Forum和Topic中的特殊屬性 Topic topic = reply.getTopic(); Forum forum = topic.getForum();
forum.setArticleCount(forum.getArticleCount()+1); //版塊的文章數量(主題+回覆)
topic.setReplyCount(topic.getReplyCount()+1); //主題回覆數量 topic.setLastReply(reply); //主題的最後回覆 topic.setLastUpdateTime(reply.getPostTime()); //主題的最後更新時間 默認爲最後回覆時間
getSession().update(forum); getSession().update(topic); }
/** * 查詢指定主題的回覆,最新回覆排到最後 */ public List<Reply> findByTopic(Topic topic) { return getSession().createQuery(// "from Reply r where r.topic = ? order by r.postTime")// .setParameter(0, topic)// .list(); }
/** * 分頁查詢指定主題的回覆,最新回覆排到最後 */ public PageBean getPageBeanByTopic(int pageNum, Topic topic) { //獲取pageSize信息 int pageSize = Configuration.getPageSize();
//查詢一頁的數據信息 List list = getSession().createQuery(// "from Reply r where r.topic=? order by r.postTime desc")// .setParameter(0, topic)// .setFirstResult((pageNum - 1) * pageSize)// .setMaxResults(pageSize)// .list();
//查詢總記錄數 Long count = (Long) getSession().createQuery(// "select count(*) from Reply r where r.topic=?")// .setParameter(0, topic)// .uniqueResult();
return new PageBean(pageNum, pageSize, count.intValue(), list); } } |
TopicAction對應的show.jsp:
…… <!-- ~~~~~~~~~~~~~~~ 顯示主帖 ~~~~~~~~~~~~~~~ --> <s:if test="currentPage == 1"><!—不寫這個判斷語句的話,不管跳到哪一頁,最上面的位置都會顯示主貼信息--> <div class="ListArea"> <table border="0" cellpadding="0" cellspacing="1" width="100%"> <tr> <td rowspan="3" width="130" class="PhotoArea" align="center" valign="top"> <!--做者頭像--> <div class="AuthorPhoto"> <img border="0" width="110" height="110" src="${pageContext.request.contextPath}/style/images/defaultAvatar.gif" onerror="this.onerror=null; this.src='${pageContext.request.contextPath}/style/images/defaultAvatar.gif';" /> </div> <!--做者名稱--> <div class="AuthorName">${topic.author.name }</div> </td> <td align="center"> <ul class="TopicFunc"> <!--操做列表--> <li class="TopicFuncLi"><a class="detail" href="${pageContext.request.contextPath}/BBS_Topic/saveUI.html"><img border="0" src="${pageContext.request.contextPath}/style/images/edit.gif" />編輯</a> <a class="detail" href="#" onClick="return confirm('肯定要刪除本帖嗎?')"><img border="0" src="${pageContext.request.contextPath}/style/images/delete.gif" />刪除</a> </li> <!-- 文章標題 --> <li class="TopicSubject"><s:property value="#topic.title" escape="true" /></li> </ul> </td> </tr> <tr> <!-- 文章內容 --> <td valign="top" align="center"> <div class="Content">${topic.content }</div> </td> </tr> <tr> <!--顯示樓層等信息--> <td class="Footer" height="28" align="center" valign="bottom"> <ul style="margin: 0px; width: 98%;"> <li style="float: left; line-height: 18px;"><font color=#C30000>[樓主]</font> <s:date name="#topic.postTime" format="yyyy-MM-dd HH:mm:ss" /></li> <li style="float: right;"><a href="javascript:scroll(0,0)"> <img border="0" src="${pageContext.request.contextPath}/style/images/top.gif" /> </a></li> </ul> </td> </tr> </table> </div> </s:if> <!-- ~~~~~~~~~~~~~~~ 顯示主帖結束 ~~~~~~~~~~~~~~~ -->
<!-- ~~~~~~~~~~~~~~~ 顯示回覆列表 ~~~~~~~~~~~~~~~ --> <s:iterator value="recordList" status="status"> …… <!--顯示樓層等信息--> <td class="Footer" height="28" align="center" valign="bottom"> <ul style="margin: 0px; width: 98%;"> <li style="float: left; line-height: 18px;"><font color=#C30000>[${(currentPage - 1) * pageSize + status.count}樓]</font> <s:date …… </s:iterator> <!-- ~~~~~~~~~~~~~~~ 顯示回覆列表結束 ~~~~~~~~~~~~~~~ --> </div>
<%@include file="/WEB-INF/jsp/public/pageView.jspf" %> <script type="text/javascript"> function gotoPage(pageNum){ window.location.href("topic_show.do?id=${id}&pageNum="+pageNum); }
</script> …… |
完善Configuration.java(其做用是讀取配置文件):
package cn.itcast.cfg; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * 管理配置信息(讀取配置文件) * @author Tan * */ public class Configuration { private static int pageSize = 10;
static{
InputStream in = null;
try {
//加載default.properties配置文件 Properties props = new Properties(); in = Configuration.class.getClassLoader().getResourceAsStream("default.properties"); props.load(in);
//獲取配置的值 pageSize = Integer.parseInt(props.getProperty("pageSize"));
} catch (Exception e) { throw new RuntimeException(e); }finally{ if(in != null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } }
}
public static int getPageSize() { return pageSize; } public static void setPageSize(int pageSize) { Configuration.pageSize = pageSize; } } |
測試是否能拿到pageSize.方法:
鼠標對着(左側包下的)Configuration.java右鍵,Newà
Nextà
Nextà
Finish後,得出一個在test包下的ConfigurationTest.java文件:
package cn.itcast.oa.test; import static org.junit.Assert.*; import org.junit.Test; public class ConfigurationTest { @Test public void testGetPageSize() { fail("Not yet implemented"); } } |
改爲這樣:
package cn.itcast.oa.test; import org.junit.Test; import cn.itcast.cfg.Configuration; public class ConfigurationTest { @Test public void testGetPageSize() { int pageSize = Configuration.getPageSize(); System.out.println("pageSize = "+pageSize); } } |
由於TopicServiceImpl和ReplyServiceImpl中有不少共同的分頁代碼,因此將他們抽取到DaoSupportImpl中.
DaoSupport:
/** * 公共的查詢分頁信息的方法 * @param pageNum * @param hql 查詢數據列表的hql語句 在方法內部會自動生成查詢總數量的hql語句 * @param args * @return */ PageBean getPageBean(int pageNum, String hql, Object[] args); |
在TopicService和ReplyService的分頁方法上加上@Deprecated,表明此方法已過期.
DaoSupportImpl:
/** * 公共的查詢分頁信息的方法 */ public PageBean getPageBean(int pageNum, String hql, Object[] args) { System.out.println("------------------->DaoSupportImpl.getPageBean()");
//獲取pageSize信息 int pageSize = Configuration.getPageSize();
//查詢一頁的數據信息 Query query = getSession().createQuery(hql); if(args != null && args.length > 0){ for(int i=0; i<args.length; i++){ query.setParameter(i, args[i]); //設置參數 } }
query.setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize); List list = query.list(); //查詢
//查詢總記錄數 query = getSession().createQuery("select count(*) "+hql); //注意空格!! if(args != null && args.length>0){ for(int i=0; i<args.length; i++){ query.setParameter(i, args[i]); } }
Long count = (Long) query.uniqueResult(); //查詢
return new PageBean(pageNum, pageSize, count.intValue(), list); } |
TopicAction:
/** 顯示單個主題 */ public String show() throws Exception { //準備數據:topic Topic topic = topicService.getById(model.getId()); ActionContext.getContext().put("topic", topic);
/*//準備數據:replyList List<Reply> replyList = replyService.findByTopic(topic); ActionContext.getContext().put("replyList", replyList);*/
/*//準備數據 V1 PageBean pageBean = replyService.getPageBeanByTopic(pageNum, topic); ActionContext.getContext().getValueStack().push(pageBean);*/
//準備數據 V2 String hql = "from Reply r where r.topic=? order by r.postTime desc"; Object[] args = { topic }; PageBean pageBean = replyService.getPageBean(pageNum, hql, args); ActionContext.getContext().getValueStack().push(pageBean);
return "show"; } |
ForumAction:
/** 顯示單個版塊(主題列表) */ public String show() throws Exception { //準備數據:forum Forum forum = forumService.getById(model.getId()); ActionContext.getContext().put("forum", forum);
/*//準備數據:topicList List<Topic> topicList = topicService.findByForum(forum); ActionContext.getContext().put("topicList", topicList);*/
/*//準備分頁的數據 V1 PageBean pageBean = topicService.getPageBeanByForum(pageNum, forum); ActionContext.getContext().getValueStack().push(pageBean);*/
//準備數據 V2 String hql = "from Topic t where t.forum = ? order by (case t.type when 2 then 2 else 0 end) desc, t.lastUpdateTime desc"; Object[] args = { forum }; PageBean pageBean = topicService.getPageBean(pageNum, hql, args); ActionContext.getContext().getValueStack().push(pageBean);
return "show"; } |
抽取出JSP和Service分頁代碼的好處:
實現分頁的正常步驟:PageBeanàActionàServiceàJSP
抽取後的步驟:PageBeanàAction(在action中須要寫好hql語句和傳遞參數) à(Service中再也不須要寫分頁代碼) àJSP(只須要導入公共的分頁代碼和傳遞id)
但到此爲止,實現的分頁效果還存在兩個缺點:1.不支持自定義檢索(過濾條件)2.把hql語句寫在了action中,耦合性變高了.
Pageview.jspf:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <!--分頁信息--> <div id=PageSelectorBar> <div id=PageSelectorMemo> 頁次:${currentPage}/${pageCount} 頁 每頁顯示:${pageSize}條 總記錄數:${recordCount}條 </div> <div id=PageSelectorSelectorArea> <a href="javascript: gotoPage(1)" title="首頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/></a>
<!-- 頁碼列表 --> <s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var="num"> <s:if test="#num != currentPage"><!-- 非當前頁,有連接 --> <span class="PageSelectorNum" style="cursor: hand;" onClick="gotoPage(${num});">${num }</span> </s:if> <s:else><!-- 當前頁,沒有連接 --> <span class="PageSelectorNum PageSelectorSelected">${num }</span> </s:else> </s:iterator>
<a href="javascript: gotoPage(${pageCount})" title="尾頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/></a>
轉到: <select id="pn" onchange="gotoPage(this.value)"> <s:iterator begin="1" end="%{pageCount}" var="num"> <option value="${num }">${num }</option> </s:iterator> </select>
<!-- 讓select默認選中當前頁 --> <script type="text/javascript"> $("#pn").val("${currentPage}"); </script>
<!-- 轉到指定的頁碼 --> <script type="text/javascript"> function gotoPage(pageNum){ //方式一 /*window.location.href = "forum_show.do?id=${id}&pageNum="+pageNum; */ //方式二 $("#pageForm").append("<input type='hidden' name='pageNum' value='"+pageNum+"'>");//添加pageNum表單字段 $("#pageForm").submit();//提交表單 } </script>
</div> </div> |
ForumAction對應的show.jsp:
<%@include file="/WEB-INF/jsp/public/pageView.jspf" %> <s:form id="pageForm" action="forum_show?id=%{id}"></s:form> |
TopicAction對應的show.jsp:
<%@include file="/WEB-INF/jsp/public/pageView.jspf" %> <s:form id="pageForm" action="topic_show?id=%{id}"></s:form> |
頁面需求是這樣的:
ForumAction對應的show.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <title>【常見問題】中的主題列表</title> <%@include file="/WEB-INF/jsp/public/header.jspf"%> <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/style/blue/forum.css" /> </head> <body>
<!-- 標題顯示 --> <div id="Title_bar"> <div id="Title_bar_Head"> <div id="Title_Head"></div> <div id="Title"> <!--頁面標題--> <img border="0" width="13" height="13" src="${pageContext.request.contextPath}/style/images/title_arrow.gif" /> 【${forum.name }】中的主題列表 </div> <div id="Title_End"></div> </div> </div>
<s:form id="pageForm" action="forum_show?id=%{id}">
<div id="MainArea"> <div id="PageHead"></div> <center> <div class="ItemBlock_Title1" style="width: 98%;"> <font class="MenuPoint"> > </font> <s:a action="forum_list">論壇</s:a> <font class="MenuPoint"> > </font> ${forum.name } <span style="margin-left: 30px;"><s:a action="topic_addUI?forumId=%{#forum.id }"> <img align="absmiddle" src="${pageContext.request.contextPath}/style/blue/images/button/publishNewTopic.png" /> </s:a> </span> </div>
<div class="ForumPageTableBorder"> <table width="100%" border="0" cellspacing="0" cellpadding="0"> <!--表頭--> <tr align="center" valign="middle"> <td width="3" class="ForumPageTableTitleLeft"><img border="0" width="1" height="1" src="${pageContext.request.contextPath}/style/images/blank.gif" /> </td> <td width="50" class="ForumPageTableTitle"> <!--狀態/圖標--> </td> <td class="ForumPageTableTitle">主題</td> <td width="130" class="ForumPageTableTitle">做者</td> <td width="100" class="ForumPageTableTitle">回覆數</td> <td width="130" class="ForumPageTableTitle">最後回覆</td> <td width="3" class="ForumPageTableTitleRight"><img border="0" width="1" height="1" src="${pageContext.request.contextPath}/style/images/blank.gif" /> </td> </tr> <tr height="1" class="ForumPageTableTitleLine"> <td colspan="8"></td> </tr> <tr height=3> <td colspan=8></td> </tr>
<!--主題列表--> <tbody class="dataContainer" datakey="topicList"> <s:iterator value="recordList"> <tr height="35" id="d0" class="template"> <td></td> <td class="ForumTopicPageDataLine" align="center"><img src="${pageContext.request.contextPath}/style/images/topicType_${type}.gif" /></td> <td class="Topic"><s:a cssClass="Default" action="topic_show?id=%{id}">${title}</s:a></td> <td class="ForumTopicPageDataLine"> <ul class="ForumPageTopicUl"> <li class="Author">${author.name}</li> <li class="CreateTime"><s:date name="postTime" format="yyyy年MM月dd日 HH:mm:ss" /></li> </ul> </td> <td class="ForumTopicPageDataLine Reply" align="center"><b>${replyCount}</b></td> <td class="ForumTopicPageDataLine"> <ul class="ForumPageTopicUl"> <li class="Author">${lastReply.author.name }</li> <li class="CreateTime"><s:date name="lastReply.postTime" format="yyyy年MM月dd日 HH:mm:ss" /></li> </ul> </td> <td></td> </tr> </s:iterator> </tbody> <!--主題列表結束-->
<tr height="3"> <td colspan="9"></td> </tr>
</table>
<!--其餘操做--> <div id="TableTail"> <div id="TableTail_inside"> <table border="0" cellspacing="0" cellpadding="0" height="100%" align="left"> <tr valign=bottom> <td></td> <td>
<!-- 使用自定義標籤,以便於回顯數據 --> <s:select name="viewType" list="%{ #{0:'所有主題', 1:'所有精華貼' } }" /> <s:select name="orderBy" list="%{ #{0:'默認排序(按最後更新時間排序,但全部置頂帖都在前面)', 1:'按最後更新時間排序', 2:'按主題發表時間排序', 3:'按回複數量排序' } }" /> <s:select name="asc" list="%{ #{true:'升序', false:'降序' } }" /> <input type="IMAGE" src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG" align="ABSMIDDLE" /></td> </tr> </table> </div> </div>
</div> </center> </div> </s:form>//這個表單能包住viewType,orderBy和asc就行了.只不過在這裏包的範圍過小的話,會阻擋頁面效果的顯示. <%@include file="/WEB-INF/jsp/public/pageView.jspf" %>
<div class="Description"> 說明:<br /> 1,主題默認按最後更新的時間降序排列。最後更新時間是指主題最後回覆的時間,若是沒有回覆,就是主題發表的時間。<br /> 2,帖子有普通、置頂、精華之分。置頂貼始終顯示在最上面,精華貼用不一樣的圖標標示。<br /> </div>
</body> </html> |
Tips:這裏的回顯是指,當用戶點擊其餘頁碼的時候,它還能記住用戶選擇的過濾條件和排序條件.
ForumAction:
package cn.itcast.oa.view.action;
import java.util.ArrayList; import java.util.List;
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Controller;
import cn.itcast.oa.base.BaseAction; import cn.itcast.oa.domain.Forum; import cn.itcast.oa.domain.PageBean; import cn.itcast.oa.domain.Topic;
import com.opensymphony.xwork2.ActionContext; @Controller @Scope("prototype") public class ForumAction extends BaseAction<Forum>{ /** * 0 表示所有主題<br> * 1 表示所有精華貼 */ private int viewType;
/** * 0 表示默認排序(全部置頂帖在前面,並按最後更新時間降序排列)<br> * 1 表示只按最後更新時間排序<br> * 2 表示只按主題發表時間排序<br> * 3 表示只按回複數量排序 */ private int orderBy;
/** * true表示升序<br> * false表示降序 */ private boolean asc;
/** 版塊列表 */ public String list() throws Exception { List<Forum> forumList = forumService.findAll(); ActionContext.getContext().put("forumList", forumList); return "list"; }
/** 顯示單個版塊(主題列表) */ public String show() throws Exception { //準備數據:forum Forum forum = forumService.getById(model.getId()); ActionContext.getContext().put("forum", forum);
/*//準備數據:topicList List<Topic> topicList = topicService.findByForum(forum); ActionContext.getContext().put("topicList", topicList);*/
/*//準備分頁的數據 V1 PageBean pageBean = topicService.getPageBeanByForum(pageNum, forum); ActionContext.getContext().getValueStack().push(pageBean);*/
/*//準備數據 V2 String hql = "from Topic t where t.forum = ? order by (case t.type when 2 then 2 else 0 end) desc, t.lastUpdateTime desc"; Object[] args = { forum }; PageBean pageBean = topicService.getPageBean(pageNum, hql, args); ActionContext.getContext().getValueStack().push(pageBean);*/
// 準備分頁的數據 V3 帶過濾條件與排序條件的 注意空格!!! List<Object> argsList = new ArrayList<Object>(); String hql = "FROM Topic t WHERE t.forum=? "; argsList.add(forum);
if (viewType == 1) { // 1 表示只看精華帖 hql += "AND t.type=? "; argsList.add(Topic.TYPE_BEST); }
if (orderBy == 1) { // 1 表示只按最後更新時間排序 hql += " ORDER BY t.lastUpdateTime " + (asc ? "ASC" : "DESC"); } else if (orderBy == 2) { // 表示只按主題發表時間排序 hql += " ORDER BY t.postTime " + (asc ? "ASC" : "DESC"); } else if (orderBy == 3) { // 表示只按回複數量排序 hql += " ORDER BY t.replyCount " + (asc ? "ASC" : "DESC"); } else { // 0 表示默認排序(全部置頂帖在前面,並按最後更新時間降序排列) hql += " ORDER BY (CASE t.type WHEN 2 THEN 2 ELSE 0 END) DESC, t.lastUpdateTime DESC"; }
Object[] args = argsList.toArray(); PageBean pageBean = topicService.getPageBean(pageNum, hql, args); ActionContext.getContext().getValueStack().push(pageBean); // 放到棧頂
return "show"; } //--------------- public int getViewType() { return viewType; }
public void setViewType(int viewType) { this.viewType = viewType; }
public int getOrderBy() { return orderBy; }
public void setOrderBy(int orderBy) { this.orderBy = orderBy; }
public boolean isAsc() { return asc; }
public void setAsc(boolean asc) { this.asc = asc; } } |
這樣能實現過濾和排序,但未免太繁瑣,方法還不能重用,下面來個最終版本.
在util包下新建一個QueryHelper.java:
package cn.itcast.oa.util;
import java.util.ArrayList; import java.util.List;
import cn.itcast.oa.base.DaoSupport; import cn.itcast.oa.domain.PageBean;
import com.opensymphony.xwork2.ActionContext;
/** * 輔助拼接HQL語句的工具類 * * @author tyg * */ public class QueryHelper {
private String fromClause; // From子句 private String whereClause = ""; // Where子句 private String orderByClause = ""; // OrderBy子句
private List<Object> parameters = new ArrayList<Object>(); // 參數列表
/** * 生成From子句 * * @param clazz * @param alias * 別名 */ public QueryHelper(Class clazz, String alias) { fromClause = "FROM " + clazz.getSimpleName() + " " + alias; }
/** * 拼接Where子句 * * @param condition * @param args */ public QueryHelper addWhereCondition(String condition, Object... args) { // 拼接 if (whereClause.length() == 0) { whereClause = " WHERE " + condition; } else { whereClause += " AND " + condition; } // 處理參數 if (args != null && args.length > 0) { for (Object arg : args) { parameters.add(arg); } } return this; }
/** * 若是第一個參數的值爲true,就拼接Where子句 * * @param append * @param condition * @param args */ public QueryHelper addWhereCondition(boolean append, String condition, Object... args) { if (append) { addWhereCondition(condition, args); } return this; }
/** * 拼接OrderBy子句 * * @param propertyName * @param asc * true表示升序,false表示降序 */ public QueryHelper addOrderByProperty(String propertyName, boolean asc) { if (orderByClause.length() == 0) { orderByClause = " ORDER BY " + propertyName + (asc ? " ASC" : " DESC"); } else { orderByClause += ", " + propertyName + (asc ? " ASC" : " DESC"); } return this; }
/** * 若是第一個參數的值爲true,就拼接OrderBy子句 * * @param append * @param propertyName * @param asc */ public QueryHelper addOrderByProperty(boolean append, String propertyName, boolean asc) { if (append) { addOrderByProperty(propertyName, asc); } return this; }
/** * 獲取查詢數據列表的HQL語句 * * @return */ public String getQueryListHql() { return fromClause + whereClause + orderByClause; }
/** * 獲取查詢總記錄數的HQL語句(沒有OrderBy子句) * * @return */ public String getQueryCountHql() { return "SELECT COUNT(*) " + fromClause + whereClause; }
/** * 獲取參數列表 * * @return */ public List<Object> getParameters() { return parameters; }
/** * 準備PageBean對象到Struts2的棧頂 * @param service * @param pageNum */ public void preparePageBean(DaoSupport<?> service, int pageNum){ PageBean pageBean = service.getPageBean(pageNum, this); ActionContext.getContext().getValueStack().push(pageBean); } } |
DaoSupport.java:
public interface DaoSupport<T> {
/** * 保存實體 */ void save(T entity);
/** * 刪除實體 */ void delete(Long id);
/** * 更新實體 */ void update(T entity);
/** * 根據id查詢 */ T getById(Long id);
/** * 根據id數組查詢多個 */ List<T> getByIds(Long[] ids);
/** * 查詢全部 */ List<T> findAll();
/** * 公共的查詢分頁信息的方法 * @param pageNum * @param hql 查詢數據列表的hql語句 在方法內部會自動生成查詢總數量的hql語句 * @param args * @return */ @Deprecated PageBean getPageBean(int pageNum, String hql, Object[] args);
/** * 公共的查詢分頁信息的方法(最終版) * * @param pageNum * @param queryHelper * 查詢語句 + 參數列表 * @return */ PageBean getPageBean(int pageNum, QueryHelper queryHelper); } |
DaoSupportImpl.java:
@SuppressWarnings("unchecked") @Transactional public abstract class DaoSupportImpl<T> implements DaoSupport<T> {
@Resource private SessionFactory sessionFactory; protected Class<T> clazz = null;
public DaoSupportImpl() { //經過反射獲取T的真實類型 this是子類 ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
System.out.println("---> clazz = " + clazz); }
/** * 獲取session */ protected Session getSession() { return sessionFactory.getCurrentSession(); }
/** * 保存實體 */ public void save(T entity) { getSession().save(entity); }
/** * 更新實體 */ public void update(T entity) { getSession().update(entity); }
/** * 刪除實體 */ public void delete(Long id) { if (id == null) { return; }
Object entity = getById(id); if (entity != null) { getSession().delete(entity); } }
/** * 根據id查詢 */ public T getById(Long id) { if(id == null){ return null; } else{ return (T) getSession().get(clazz, id); } }
/** * 根據id數組查詢多個 */ public List<T> getByIds(Long[] ids) { if(ids == null || ids.length == 0){ return Collections.EMPTY_LIST; }
// 注意空格 sql語句:from與類名之間有一空格不能省略 類名與where之間有一空格不能省略 return getSession().createQuery(// "from " + clazz.getSimpleName() + " where id in (:ids)")// .setParameterList("ids", ids)//注意:必定要使用setParameterList()方法 .list(); }
/** * 查詢全部 */ public List<T> findAll() { // 注意空格 return getSession().createQuery("from " + clazz.getSimpleName()).list(); }
/** * 公共的查詢分頁信息的方法 */ public PageBean getPageBean(int pageNum, String hql, Object[] args) { System.out.println("------------------->DaoSupportImpl.getPageBean()");
//獲取pageSize信息 int pageSize = Configuration.getPageSize();
//查詢一頁的數據信息 Query query = getSession().createQuery(hql); if(args != null && args.length > 0){ for(int i=0; i<args.length; i++){ query.setParameter(i, args[i]); //設置參數 } }
query.setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize); List list = query.list(); //查詢
//查詢總記錄數 query = getSession().createQuery("select count(*) "+hql); //注意空格!! if(args != null && args.length>0){ for(int i=0; i<args.length; i++){ query.setParameter(i, args[i]); } }
Long count = (Long) query.uniqueResult(); //查詢
return new PageBean(pageNum, pageSize, count.intValue(), list); }
/** * 公共的查詢分頁信息的方法(最終版) * * @param pageNum * @param queryHelper * 查詢語句 + 參數列表 * @return */ public PageBean getPageBean(int pageNum, QueryHelper queryHelper) { System.out.println("------------> DaoSupportImpl.getPageBean( int pageNum, QueryHelper queryHelper )");
// 獲取pageSize等信息 int pageSize = Configuration.getPageSize(); List<Object> parameters = queryHelper.getParameters();
// 查詢一頁的數據列表 Query query = getSession().createQuery(queryHelper.getQueryListHql()); if (parameters != null && parameters.size() > 0) { // 設置參數 for (int i = 0; i < parameters.size(); i++) { query.setParameter(i, parameters.get(i)); } } query.setFirstResult((pageNum - 1) * pageSize); query.setMaxResults(pageSize); List list = query.list(); // 查詢
// 查詢總記錄數 query = getSession().createQuery(queryHelper.getQueryCountHql()); // 注意空格! if (parameters != null && parameters.size() > 0) { // 設置參數 for (int i = 0; i < parameters.size(); i++) { query.setParameter(i, parameters.get(i)); } } Long count = (Long) query.uniqueResult(); // 查詢
return new PageBean(pageNum, pageSize, count.intValue(), list); } } |
ForumAction:
@Controller @Scope("prototype") public class ForumAction extends BaseAction<Forum>{ /** * 0 表示所有主題<br> * 1 表示所有精華貼 */ private int viewType;
/** * 0 表示默認排序(全部置頂帖在前面,並按最後更新時間降序排列)<br> * 1 表示只按最後更新時間排序<br> * 2 表示只按主題發表時間排序<br> * 3 表示只按回複數量排序 */ private int orderBy;
/** * true表示升序<br> * false表示降序 */ private boolean asc;
/** 版塊列表 */ public String list() throws Exception { List<Forum> forumList = forumService.findAll(); ActionContext.getContext().put("forumList", forumList); return "list"; }
/** 顯示單個版塊(主題列表) */ public String show() throws Exception { //準備數據:forum Forum forum = forumService.getById(model.getId()); ActionContext.getContext().put("forum", forum);
/*//準備數據:topicList List<Topic> topicList = topicService.findByForum(forum); ActionContext.getContext().put("topicList", topicList);*/
/*//準備分頁的數據 V1 PageBean pageBean = topicService.getPageBeanByForum(pageNum, forum); ActionContext.getContext().getValueStack().push(pageBean);*/
// //準備數據 V2 // String hql = "from Topic t where t.forum = ? order by (case t.type when 2 then 2 else 0 end) desc, t.lastUpdateTime desc"; // Object[] args = { forum }; // PageBean pageBean = topicService.getPageBean(pageNum, hql, args); // ActionContext.getContext().getValueStack().push(pageBean);
/*// 準備分頁的數據 V3 帶過濾條件與排序條件的 List<Object> argsList = new ArrayList<Object>(); String hql = "FROM Topic t WHERE t.forum=? "; argsList.add(forum);
if (viewType == 1) { // 1 表示只看精華帖 hql += "AND t.type=? "; argsList.add(Topic.TYPE_BEST); }
if (orderBy == 1) { // 1 表示只按最後更新時間排序 hql += " ORDER BY t.lastUpdateTime " + (asc ? "ASC" : "DESC"); } else if (orderBy == 2) { // 表示只按主題發表時間排序 hql += " ORDER BY t.postTime " + (asc ? "ASC" : "DESC"); } else if (orderBy == 3) { // 表示只按回複數量排序 hql += " ORDER BY t.replyCount " + (asc ? "ASC" : "DESC"); } else { // 0 表示默認排序(全部置頂帖在前面,並按最後更新時間降序排列) hql += " ORDER BY (CASE t.type WHEN 2 THEN 2 ELSE 0 END) DESC, t.lastUpdateTime DESC"; }
Object[] args = argsList.toArray(); PageBean pageBean = topicService.getPageBean(pageNum, hql, args); ActionContext.getContext().getValueStack().push(pageBean); // 放到棧頂*/
// 準備分頁的數據 v4 (最終版)-- 使用QueryHelper new QueryHelper(Topic.class, "t")// .addWhereCondition("t.forum=?", forum)// .addWhereCondition((viewType == 1), "t.type=?", Topic.TYPE_BEST) // 1 表示只看精華帖 .addOrderByProperty((orderBy == 1), "t.lastUpdateTime", asc) // 1 表示只按最後更新時間排序 .addOrderByProperty((orderBy == 2), "t.postTime", asc) // 表示只按主題發表時間排序 .addOrderByProperty((orderBy == 3), "t.replyCount", asc) // 表示只按回複數量排序 .addOrderByProperty((orderBy == 0), "(CASE t.type WHEN 2 THEN 2 ELSE 0 END)", false)// .addOrderByProperty((orderBy == 0), "t.lastUpdateTime", false) // 0 表示默認排序(全部置頂帖在前面,並按最後更新時間降序排列) .preparePageBean(topicService, pageNum); return "show"; } //--------------- public int getViewType() { return viewType; }
public void setViewType(int viewType) { this.viewType = viewType; }
public int getOrderBy() { return orderBy; }
public void setOrderBy(int orderBy) { this.orderBy = orderBy; }
public boolean isAsc() { return asc; }
public void setAsc(boolean asc) { this.asc = asc; } } |
TopicAction:
@Controller @Scope("prototype") public class TopicAction extends BaseAction<Topic> {
private Long forumId;
/** 顯示單個主題 */ public String show() throws Exception { // 準備數據:topic Topic topic = topicService.getById(model.getId()); ActionContext.getContext().put("topic", topic);
/* * //準備數據:replyList List<Reply> replyList = * replyService.findByTopic(topic); * ActionContext.getContext().put("replyList", replyList); */
/* * //準備數據 V1 PageBean pageBean = * replyService.getPageBeanByTopic(pageNum, topic); * ActionContext.getContext().getValueStack().push(pageBean); */
/* * //準備數據 V2 String hql = * "from Reply r where r.topic=? order by r.postTime desc"; Object[] * args = { topic }; PageBean pageBean = * replyService.getPageBean(pageNum, hql, args); * ActionContext.getContext().getValueStack().push(pageBean); */
// 準備分頁的數據 (最終版) new QueryHelper(Reply.class, "r")// .addWhereCondition("r.topic=?", topic)// .addOrderByProperty("r.postTime", true)// .preparePageBean(replyService, pageNum);
return "show"; }
/** 發新帖頁面 */ public String addUI() throws Exception { // 準備數據:forum Forum forum = forumService.getById(forumId); ActionContext.getContext().put("forum", forum); return "addUI"; }
/** 發新帖 */ public String add() throws Exception { // 封裝對象 Topic topic = new Topic(); // 須要在action中封裝的數據: // >>a.表單中的參數 topic.setTitle(model.getTitle()); topic.setContent(model.getContent()); topic.setForum(forumService.getById(forumId)); // >>b.在顯示層才能得到的數據 topic.setAuthor(getCurrentUser()); // 當前登陸的用戶 topic.setIpAddr(getRequestIp()); // 客戶端的IP地址
// 調用業務方法 topicService.save(topic);
ActionContext.getContext().put("topicId", topic.getId()); return "toShow"; // 轉到當前這個 新主題的頁面 }
// ----------------------------------- public Long getForumId() { return forumId; }
public void setForumId(Long forumId) { this.forumId = forumId; } } |
QueryHelper.javaàDaoSupport,DaoSupportImplàPageView.jspàPageBean
àAction(只須要寫一行長長的代碼) àService(不用寫) àJSP頁面(只須要導入PageView.jsp,寫form表單,將遍歷對象改爲recordList.若是是主題顯示列表的話,還要將過濾和排序那塊改爲用Struts2標籤的形式,便於回顯數據.)
如下圖片僅做參考:
PageBean:
package cn.itcast.oa.domain;
import java.util.List;
/** * 分頁用的一頁的信息對象 * @author Tan * */ public class PageBean { //傳遞的參數或配置的值 private int currentPage; //當前頁 private int pageSize; //每頁顯示的記錄數 //查詢數據庫 private int recordCount; //總記錄數 private List recordList; //本頁的數據列表 //計算出來的 private int pageCount; //總頁數 private int beginPageIndex; //頁面列表的開始索引 private int endPageIndex; //頁面列表的結束索引
/** * 只接受前四個屬性的值,會自動計算後四個屬性的值 * @param currentPage * @param pageSize * @param recordCount * @param recordList */ public PageBean(int currentPage, int pageSize, int recordCount, List recordList) { this.currentPage = currentPage; this.pageSize = pageSize; this.recordCount = recordCount; this.recordList = recordList;
//計算pageCount總頁數 pageCount = (recordCount + pageSize - 1)/ pageSize;
//計算beginPageIndex和endPageIndex //a.若是總頁數不超過十頁,就所有顯示 if(pageCount <= 10){ beginPageIndex = 1; endPageIndex = pageCount; //b.若是總頁數超過十頁,就顯示當前頁附近的共10個頁碼,(前4頁+當前頁+後5頁) }else{ //就顯示當前頁附近的共10個頁碼,(前4頁+當前頁+後5頁) beginPageIndex = currentPage - 4; endPageIndex = currentPage + 5;
//若是前面不足4個頁碼,就顯示前10頁 if(beginPageIndex < 1){ beginPageIndex = 1; endPageIndex = 10;
//若是後面不足5個頁碼,就顯示後10頁 }else if(endPageIndex > pageCount){ endPageIndex = pageCount; beginPageIndex = pageCount - 10 + 1; //注意:在顯示的時候是包含兩個邊界的 } } } Get,set方法… } |
Pageview:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <!--分頁信息--> <div id=PageSelectorBar> <div id=PageSelectorMemo> 頁次:${currentPage}/${pageCount} 頁 每頁顯示:${pageSize}條 總記錄數:${recordCount}條 </div> <div id=PageSelectorSelectorArea> <a href="javascript: gotoPage(1)" title="首頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/firstPage.png"/></a>
<!-- 頁碼列表 --> <s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var="num"> <s:if test="#num != currentPage"><!-- 非當前頁,有連接 --> <span class="PageSelectorNum" style="cursor: hand;" onClick="gotoPage(${num});">${num }</span> </s:if> <s:else><!-- 當前頁,沒有連接 --> <span class="PageSelectorNum PageSelectorSelected">${num }</span> </s:else> </s:iterator>
<a href="javascript: gotoPage(${pageCount})" title="尾頁" style="cursor: hand;"> <img src="${pageContext.request.contextPath}/style/blue/images/pageSelector/lastPage.png"/></a>
轉到: <select id="pn" onchange="gotoPage(this.value)"> <s:iterator begin="1" end="%{pageCount}" var="num"> <option value="${num }">${num }</option> </s:iterator> </select>
<!-- 讓select默認選中當前頁 --> <script type="text/javascript"> $("#pn").val("${currentPage}"); </script>
<!-- 轉到指定的頁碼 --> <script type="text/javascript"> function gotoPage(pageNum){ //方式一 /*window.location.href = "forum_show.do?id=${id}&pageNum="+pageNum; */ //方式二 $("#pageForm").append("<input type='hidden' name='pageNum' value='"+pageNum+"'>");//添加pageNum表單字段 $("#pageForm").submit();//提交表單 } </script>
</div> </div> |
QueryHelper.java,DaoSupport.java,DaoSupportImpl.java,PageBean.java,pageview.jsp前面已經作好了,接下來再作分頁,只須要在Action和jsp中寫少許代碼便可:
UserAction:
/** 列表 */ public String list() throws Exception {
/*List<User> userList = userService.findAll(); ActionContext.getContext().put("userList", userList);*/
new QueryHelper(User.class, "u").preparePageBean(userService, pageNum);
return "list"; } |
UserAction對應的list.jsp:
<s:iterator value="recordList"> <tr class="TableDetail1 template"> <td>${loginName} </td> <td>${name} </td> <td>${department.name} </td>
<td> <s:iterator value="roles"> ${name} </s:iterator> </td>
<td>${description} </td> <td><s:a action="user_delete?id=%{id}" onClick="return delConfirm()">刪除</s:a> <s:a action="user_editUI?id=%{id}" >修改</s:a> <s:a action="user_initPassword?id=%{id}" onClick="return window.confirm('您肯定要初始化密碼爲1234嗎?')"> 初始化密碼</s:a> </td> </tr> </s:iterator> <%@include file="/WEB-INF/jsp/public/pageView.jspf" %> <s:form id="pageForm" action="user_list"></s:form> |