步骤: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> |