经过几天业余时间的研究,已经做了一套关于分页的高效解决方案,所谓的高效,就是在数据库底层,也做了分页查询,因此在进行大数据量的查询时,速度会很快。如果不做底层的分页的话,数据量超过5W,速度将会慢的象乌龟一样。
这套解决方案,是按照MVC的模式来做的,基于STRUTS框架。分为三个部分,表现层用的是JSP,其中用了JSTL和pager taglib做分页;控制层就是用的很传统的Action;底层就用的是Spring+Hibernate。下面分三个部分慢慢说:
一、底层:
底层是基于Spring+Hibernate来做的。在DAO这一层,为其增加两个方法,一个方法为根据HQL语句和条件进行查询,另外一个方法为根据HQL语句、条件、开始的记录位置,共显示的记录数进行分页查询。底层的分页查询用的是Hibernate提供的分页查询。
方法体如下所示:
DAO 代码
1
public List findByCondition(String sql,Object[] parems)
{
2
3
List result = new ArrayList();
4
5
try
{
6
7
result = getHibernateTemplate().find(sql,parems);
8
9
}catch(RuntimeException re)
{
10
11
re.printStackTrace();
12
13
}
14
15
return result;
16
17
}
18
19
20
21
public List findByCondition(String sql,Object[] parems,int first,int max)
{
22
23
List result = new ArrayList();
24
25
try
{
26
27
Session sess = getSession();
28
29
Query query = sess.createQuery(sql);
30
31
for(int i = 0;i<parems.length;i++)
{
32
33
if(parems[i] instanceof Integer)
{
34
35
query.setInteger(i,((Integer)parems[i]).intValue());
36
37
}
38
39
if(parems[i] instanceof String)
{
40
41
query.setString(i,parems[i].toString());
42
43
}
44
45
}
46
47
query.setFirstResult(first);
48
49
query.setMaxResults(max);
50
51
result = query.list();
52
53
}catch(RuntimeException re)
{
54
55
re.printStackTrace();
56
57
}
58
59
return result;
60
61
}
62
OK,底层的工作就做完了!
现在说中间的控制层。
在Struts的FORM中,增加private int pageDisplay = 10; 属性,并增加对应的setter和getter方法。这个属性是用来设置每页显示的记录数,10是默认值,可以根据实际情况进行设置。
在Struts的ACTION层,增加一个方法,代码如下:
1
package com.excellence.struts.action;
2
3
4
import java.util.List;
5
6
7
import javax.servlet.http.HttpServletRequest;
8
9
import javax.servlet.http.HttpServletResponse;
10
11
12
import org.apache.struts.action.Action;
13
14
import org.apache.struts.action.ActionForm;
15
16
import org.apache.struts.action.ActionForward;
17
18
import org.apache.struts.action.ActionMapping;
19
20
21
import com.excellence.page.Service;
22
23
import com.excellence.struts.form.CheckForm;
24
25
public class CheckAction extends Action
{
26
27
public ActionForward execute(
28
29
ActionMapping mapping,
30
31
ActionForm form,
32
33
HttpServletRequest request,
34
35
HttpServletResponse response)
{
36
37
38
39
setSubPage(request,form);
40
41
42
43
return mapping.findForward("result");
44
45
}
46
47
48
49
private void setSubPage(HttpServletRequest request,ActionForm form)
{
50
51
CheckForm thisForm = (CheckForm)form;
52
53
String content = thisForm.getContent();//查询条件中的内容
54
55
Service service = new Service();
56
57
58
59
//拿到每页要显示的记录数
60
61
int pageSize = thisForm.getPageDisplay();
62
63
request.setAttribute("pageSize",pageSize+"");
64
65
//拿到目前要显示得页数
66
67
int pageNumber = 1;
68
69
String strPageNumber = request.getParameter("page");
70
71
if(strPageNumber != null)
72
73
pageNumber = Integer.parseInt(strPageNumber);
74
75
//计算要显示的页数得第一条记录的位置
76
77
int start = 0;
78
79
start = (pageNumber - 1)*pageSize;
80
81
82
83
List result = service.findByCondition("from Subpage where content like ? order by content",new Object[]
{content},start,pageSize);
84
85
List counts = service.findByCondition("select count(*) from Subpage where content like ?",new Object[]
{content});
86
87
int count = Integer.parseInt(counts.get(0).toString());
88
89
request.setAttribute("count",count+"");//总条数
90
91
92
93
// 设置总页数
94
95
int totalPage = count % pageSize == 0 ? count / pageSize : (count / pageSize + 1);
96
97
request.setAttribute("totalPage",totalPage+"");
98
99
100
101
request.setAttribute("result",result);
102
103
if(result.size() == 0)
104
105
request.setAttribute("result",null);
106
107
}
108
109
}
110
111
112
主要就是增加了一个私有的方法private void setSubPage(HttpServletRequest request,ActionForm form)。
下面说说表现层,代码如下:
1
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
2
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
3
<%@ taglib uri="/WEB-INF/c.tld" prefix="c"%>
4
<%@ taglib uri="http://jsptags.com/tags/navigation/pager" prefix="pg"%>
5
6
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
7
<script type="text/javascript">
8
function changePageSize()
{
9
document.forms[0].submit();
10
}
11
//直接跳转到某个页面
12
function jumpPage()
{
13
var page = document.getElementById('page').value;
14
var offset = (page -1 )*document.getElementsByName('pageDisplay')[0].value;
15
document.location.href('check.do?pager.offset='+offset+'&page='+page);
16
}
17
</script>
18
<html>
19
<head>
20
21
<title>My JSP 'index.jsp' starting page</title>
22
23
<meta http-equiv="pragma" content="no-cache">
24
<meta http-equiv="cache-control" content="no-cache">
25
<meta http-equiv="expires" content="0">
26
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
27
<meta http-equiv="description" content="This is my page">
28
29
<!--
30
<link rel="stylesheet" type="text/css" href="styles.css">
31
-->
32
</head>
33
34
<body>
35
<!-- 查询条件部分 -->
36
<html:form action="/check.do" method="post">
37
<table>
38
<tr>
39
<td>
40
内容:
41
</td>
42
</tr>
43
<tr>
44
<td>
45
<html:text property="content" />
46
</td>
47
</tr>
48
<tr>
49
<td>
50
<input type="submit" />
51
</td>
52
</tr>
53
</table>
54
55
56
57
<!-- 数据显示部分 -->
58
<c:if test="${result != null}">
59
<pg:pager items="${count}" maxPageItems="${pageSize}" index="center" maxIndexPages="5" export="offset,currentPageNumber=pageNumber" scope="request" url="check.do">
60
61
62
数据:<br />
63
64
<table width="100%" border="1">
65
<c:forEach items="${result}" var="subpage">
66
67
<tr>
68
<td>
69
<c:out value="${subpage.content}"></c:out>
70
</td>
71
<td>
72
<c:out value="${subpage.intValue}"></c:out>
73
</td>
74
</tr>
75
76
</c:forEach>
77
</table>
78
79
<pg:index>
80
第
81
<select id="page" onchange="jumpPage();">
82
<pg:pages>
83
<c:if test="${pageNumber == currentPageNumber}">
84
<option value="${pageNumber}" selected="selected" >$
{pageNumber}</option>
85
</c:if>
86
<c:if test="${pageNumber != currentPageNumber}">
87
<option value="${pageNumber}" >$
{pageNumber}</option>
88
</c:if>
89
</pg:pages>
90
</select>
91
页
92
共<c:out value="${totalPage }"></c:out>页
93
<pg:first>
94
<a href="<%= pageUrl %>&page=${pageNumber}">首页</a>
95
</pg:first>
96
97
<pg:prev>
98
<a href="<%= pageUrl %>&page=${pageNumber}">上一页</a>
99
</pg:prev>
100
101
<pg:next>
102
<a href="<%= pageUrl %>&page=${pageNumber }">下一页</a>
103
</pg:next>
104
105
<pg:last>
106
<a href="<%= pageUrl %>&page=${pageNumber }">末页</a>
107
</pg:last>
108
共$
{count}条记录
109
110
每页显示
111
<html:text property="pageDisplay" onchange="changePageSize();"/>
112
条记录
113
114
</pg:index>
115
116
</pg:pager>
117
</c:if>
118
</html:form>
119
</body>
120
</html>
121
注意:若要采用DispatchAction的话,需要进行以下更改,注意isOffset="true",多了一个<pg:param name="method" value="list" />
1
<pg:pager items="${count}" maxPageItems="${pageSize}" index="center"
2
maxIndexPages="5" isOffset="true" export="offset,currentPageNumber=pageNumber"
3
scope="request" url="managerInterview.do">
4
<pg:param name="method" value="list" />
java 代码
posted on 2009-06-12 11:12
方涛升 阅读(669)
评论(1) 编辑 收藏 所属分类:
j2ee