本文主要说的是关于在展示层一些常用的方案和实现,目录如下:
手工实现分页
- 用eXtremeTable标签实现自动分页
- 用oscache缓存jsp,提高性能
第一.自己实现一个工具类PageBean完成所有分页工作.
本分页实现概览:Struts + hibernate
PageBean负责两部分内容,一是要在页面显示的业务信息,是一个ArrayList;另一个是逻辑控制信息,诸如是否有下一页,上一页等等.
PageBean代码如下:<!---->public class PageBean {
int currentPage = 1;//当前页:Action控制
int totalPages = 0;//总页数 :自己运算
int pageRecorders = 5; //每页记录数,默认为5,可以在初始化的时候修改//总数据数
int pageStartRow = 0; //每页的起始数
int pageEndRow = 0; //每页显示数据的终止数
boolean hasNextPage = false; //是否有下一页:自己运算
boolean hasPreviousPage = false; //是否有前一页 :自己运算
List objList = new ArrayList();//存放欲展示的对象列表
int totalRows;//总记录数,由底层service提供
//是否有上一页
public boolean isHasPreviousPage() {
return (currentPage > 1?true:false );
}
//共有多少页,service只提供有多少条记录,多少页数由PageBean自己运算
public int getTotalPages() {
return (totalRows/pageRecorders ==0?totalRows/pageRecorders:totalRows/pageRecorders+1);
}
public int getCurrentPage() {
return currentPage;
}
public int getPageEndRow() {
return pageEndRow;
}
//是否有下一页
public boolean isHasNextPage() {
return (currentPage < this.getTotalPages() ? true:false);
}
public int getTotalRows() {
return totalRows;
}
public int getPageStartRow() {
return pageStartRow;
}
public int getPageRecorders() {
return pageRecorders;
}
public void setObjList(List objList) {
this.objList = objList;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public void setPageEndRow(int pageEndRow) {
this.pageEndRow = pageEndRow;
}
public void setHasNextPage(boolean hasNextPage) {
this.hasNextPage = hasNextPage;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public void setPageStartRow(int pageStartRow) {
this.pageStartRow = pageStartRow;
}
public void setPageRecorders(int pageRecorders) {
this.pageRecorders = pageRecorders;
}
public List getObjList() {
return objList;
}
public PageBean() {}
public void description() {
String description = "共有数据数:" + this.getTotalRows() +
"共有页数: " + this.getTotalPages() +
"当前页数为:" + this.getCurrentPage() +
" 是否有前一页: " + this.isHasPreviousPage() +
" 是否有下一页:" + this.isHasNextPage() +
" 开始行数:" + this.getPageStartRow() +
" 终止行数:" + this.getPageEndRow();
System.out.println(description);
}
}
注意,我没有在PageBean里放具体的业务逻辑,诸如getBooks()等,目的很简单,具有通用性,业务逻辑由另一个业务类实现BookService,BookService获得的业务数据都放在了PageBean的ArrayList里.
BookService代码如下:<!---->public class BookService {
private static Logger log = Logger.getLogger(BookService.class.getName());
public BookService() {
}
/**
* 获得book列表
* @param pageBean PageBean:返回的对象存在pageBean里
*/
public static void getBooks(PageBean pageBean) {
String infoSql = "from Book";//获得业务信息
String countSql = "select count(*) from Book";//获得控制信息
Session session = null;
try {
session = DBUtil.currentSession();
Query query = session.createQuery(infoSql);
query.setFirstResult((pageBean.getCurrentPage()-1)* pageBean.getPageRecorders());//起始页
query.setMaxResults(pageBean.getPageRecorders());//每页记录数
pageBean.getObjList().clear();
for (Iterator it = query.iterate(); it.hasNext(); ) {
Book po = (Book)it.next();
BookVo vo = new BookVo();
BeanUtils.copyProperties(vo,po);
pageBean.getObjList().add(vo);
}
session = DBUtil.currentSession();
query = session.createQuery(countSql);
int totalRecords = ((Integer)query.list().get(0)).intValue();
pageBean.setTotalRows(totalRecords);
}
catch (Exception e) {
e.printStackTrace();
System.out.println("数据库异常" + e.toString());
}
finally {
try {
if (null != session) {
session.close();
}
}
catch (HibernateException ex) {
ex.printStackTrace();
}
}
}
}
在Struts的Action中调用service,返回一个PageBean给展示页面
Action代码如下:<!----> 1 public class PageListAction extends Action {
2
3 public PageListAction() {}
4
5 ArrayList arrayList = new ArrayList();
6
7 public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception {
8 String action;
9 PageBean pageBean = null;
10 action = request.getParameter("action");
11 if(action == null || action.equals("null")) { //第一次读取数据
12 pageBean = new PageBean();
13 } else {//用户选择上一页或者下一页
14 if(action == "nextPage" || action.equals("nextPage")) {
15 pageBean = (PageBean)request.getSession().getAttribute("pageBean");
16 pageBean.setCurrentPage(pageBean.getCurrentPage()+1);
17 }else if(action == "previousPage" || action.equals("previousPage")) {
18 pageBean = (PageBean)request.getSession().getAttribute("pageBean");
19 pageBean.setCurrentPage(pageBean.getCurrentPage()-1);
20 }else if(action == "targetPage" || action.equals("targetPage")){//指定页
21 pageBean = (PageBean)request.getSession().getAttribute("pageBean");
22 System.out.println("targetPage=" + request.getParameter("targetPage"));
23 //这里根据需要可以对填写的目标页进行判断,不要大于最大页数[此处省略]
24 pageBean.setCurrentPage(Integer.parseInt(request.getParameter("targetPage")));
25 }
26 }
27 if(null == pageBean) throw new Exception("获得PageBean异常");
28 BookService service = new BookService();
29 service.getBooks(pageBean);
30 pageBean.description();
31 request.getSession().setAttribute("pageBean",pageBean);
32 request.setAttribute("result",pageBean.getObjList());
33 return(mapping.findForward("success"));
34 }
35 }
在本Action中判断了可能出现的三种情况:
- 用户选择了"上一页"
- 用户选择了"下一页"
- 用户手工输入了指定的某一页
这里有点感觉不爽的是必须hard coding,但是不这么做感觉暂时也想不出什么好的办法来,毕竟一个PageBean不可能封装所有的细节,如果你有更好的方式请指点哦 :)
好了,到了我们呼之欲出的展示页面了 :)
show.jsp代码如下
<!----><%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ page contentType="text/html; charset=gb2312" language="java"%>
<html:html locale="true">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<script language="javaScript">
function go(){
try{
var targetValue = document.getElementById("targetPage").value;
parseInt(targetValue);
alert(targetValue);
}catch(e){
alert("请正确填写目标页");
return;
}
if(targetValue == null || targetValue == ''){
alert("请填写目标页");
return;
}
window.location = "//pageList.do?action=targetPage&targetPage="+targetValue;
}
</script>
</head>
<body>
<logic:present name="pageBean">
共有数据总数<bean:write name="pageBean" property="totalRows"/>;
共分<bean:write name="pageBean" property="totalPages"/>页,
当前是第<bean:write name="pageBean" property="currentPage"/>页
</logic:present>
<table border="1">
<tr><th>书名</th><th>作者</th><th>价格</th></tr>
<logic:present name="result">
<logic:iterate id="book" name="result">
<logic:present name="book">
<tr>
<td><bean:write name="book" property="name" /></td>
<td> <bean:write name="book" property="author" /></td>
<td><bean:write name="book" property="price" /></td>
/tr>
</logic:present>
</logic:iterate>
</logic:present>
</table>
<logic:present name="pageBean">
<logic:equal name="pageBean" property="hasNextPage" value="true">
<html:link page="/pageList.do?action=nextPage">nextPage</html:link>
</logic:equal>
<logic:equal name="pageBean" property="hasPreviousPage" value="true">
<html:link page="/pageList.do?action=previousPage">PreviousPage</html:link>
</logic:equal>
<input type="text" name="targetPage" id="targetPage"/>
<input type="button" value="go!" size="2" onclick="go();"/>
</logic:present>
</body>
</html:html>
是否有上一页或者下一页,全部根据PageBean里的逻辑值动态判断.
这个页面没什么可说的,你可以根据自己的情况调整就OK了
第二. 用eXtremeTable标签实现自动分页
上面的方案大家已经看出来了,实际上是每一次用户点击一个页面都会查询数据库,这可以算是既是优点也是缺点,优点是数据库不用一次查询出所有的数据,在高数据量的情况下尤其如此,缺点就是和数据库的交互次数有点多了,不过这个完全看你的业务策略了,如果用户大多数情况下就是看没几条的记录,你又何必把全部数据给他取出来呢? 当然,在这里我们就说说一次取出全部数据,然后让标签帮助我们自动分页,终于可以偷懒了,你所要做的仅仅是取出所需要的业务数据而已,其他的就交给eXtremeTable标签来完成就OK了.
eXtremeTable标签的下载,安装和文档请参看
官方网站<!---->public static List getBooks() {
log.debug("execute getBooks method!");
String infoSql = "from Book";//获得业务信息
Session session = null
分享到:
相关推荐
在Java Swing应用开发中,`JTable`是一个常用的组件,用于展示二维数据表格。当数据量较大时,一次性加载所有数据不仅效率低下,也可能导致界面响应缓慢。因此,实现`JTable`的分页显示是优化用户体验的重要手段。这...
Entity Framework是Microsoft开发的一个对象关系映射(ORM)框架,它允许开发者使用.NET语言来操作数据库,而无需直接编写SQL语句。这里的“分页类代码”指的是实现数据库查询结果分页显示的C#代码。 **描述分析:*...
【标签】"网站"明确了这是一个与网站开发相关的资源,适用于那些想要建立信息分类网站或者对网站编程有兴趣的个人或团队。 以下是一些基于给定的文件名可能涵盖的关键知识点: 1. **Add.asp**:这是一个添加信息的...
循环弹出窗口:页面打开时同时弹出一个窗口,在同一窗口内循环显示广告位中的正常广告,这样,每刷新一次就会在弹出窗口中更替显示一个新的广告条 只需后台修改广告即可更新广告;可设置广告过期时间,通用于站内...
iReport主要支持JasperReport XML标签,并且提供了一个所见即所得的报表编辑器,使得用户能够轻松地创建复杂的报表。此外,iReport还支持多种数据源,包括所有可以通过JDBC连接的数据库,并且支持Unicode,使得在...
香香企业文章管理系统是全站采用主流DIV CSS框架布局,功能强大,操作人性化,有五种不同模式,可以适用于广泛的新闻发布型网站,让不懂代码但又想建立自己网站的朋友,通过后台简单的配置,就能拥有一个个性化的...
十、如果您有什么建议或意义,也请告诉我们,一个完善的系统离不开大家的建议和意见。 欢迎使用网钛文章管理系统! 谢谢支持网钛文章管理系统! ★★★网钛文章管理系统功能介绍★★★ 网钛文章管理系统是全...
循环弹出窗口:页面打开时同时弹出一个窗口,在同一窗口内循环显示广告位中的正常广告,这样,每刷新一次就会在弹出窗口中更替显示一个新的广告条 广告文件支持: 图片、动画、纯文本、嵌入代码、植入网页 只需...
循环弹出窗口:页面打开时同时弹出一个窗口,在同一窗口内循环显示广告位中的正常广告,这样,每刷新一次就会在弹出窗口中更替显示一个新的广告条 广告文件支持: 图片、动画、纯文本、嵌入代码、植入网页 只需后台...