在網上看了幾個Structs分頁
感覺不是很完善
於是根據自己的經驗
寫了一個相對高效簡潔的分頁方法
由於本人水平有限
如果大家有什麼更好的想法
歡迎不吝賜教
一 開發環境 我的開發環境是
JBuilder x + Weblogic
+ Oracle
i + Windows
如果朋友們的開發環境不一樣亦無妨
二開發思路 既然講的是Struts
那自然離不了MVC
分頁顯示也是如此
建立數據庫和對應的表
本例的表是TCertificate
建立適當的模型組件
對應你要查詢數據庫中的表
這部分由DAO數據訪問層來實現
如果有的朋友對DAO不熟悉可以查詢一下相關資料
本例由CertificateDAO
java來實現
建立分頁所需要的模型組件
由javaBean來充當
並與CertificateDAO實現分離
網上介紹的很多方法
都存在著數據與分頁組件藕合的現象
這也是本方法與其它分頁方法的主要不同之處
建立控制器組件
這部分由Struts 中的Action來實現
主要負責將實例化CertificateDAO
只取要顯示的數據記錄
存入ArrayList對象然後返回
並放到request中
而分頁部分則根據分頁條件
單獨進行構造
避免了與DAO混在一起的情況發生
網上其它介紹的一些分頁方法中
基本上都是一次性讀出所有查詢的數據
然後再由分頁相關組件進行構造
這樣
如果數據量大的話
很容易形成瓶頸
在本例中由於不是一次性地讀出查詢的所有數據
而只是讀出一個頁面要顯示的數據記錄
這就節省了很多不必要的數據傳輸
提高了效率
本例中為CertificateAction
java
建立視圖組件
這部分由jsp來充當
為了不出現java 代碼
我們使用Struts提供的標簽庫
主要負責從request中取出剛剛放入的對象
通過反復調用CertificateAction以及action參數
而實現分頁顯示
本例中為listcertificate
jsp
建立並配置struts
config
xml
三實例代碼 確定好上面的開發思路後
代碼的實現就有單可循了
建數據庫和相應的表
數據邏輯層的相關代碼
)
通用的DAO類
CommonDAO
java
這是一個很多DAO都要繼承到的通用DAO類
是我根據實踐總結出來的
為了減少篇幅
這裡只顯示和本例相關的代碼
java代碼:
代碼
package com
xindeco
business ;
import java
io
*;
import java
sql
*;
import java
util
*;
import javax
sql
*;
import java
lang
IllegalAccessException;
import java
lang
reflect
InvocationTargetException;
import mons
beanutils
BeanUtils;
public class DAO
{
protected DataSource ds;
/**
* 說明:取得當前查詢的總記錄數
*/
public int getRows ()
{
return unt;
}
public void rsHandler (ResultSet rs
int offset
int limit)
{
try
{
count =
;
rs
absolute (
) ;
count = rs
getRow () ;
if (offset <=
)
{
rs
beforeFirst () ;
}
else
{
rs
absolute (offset) ;
}
}
catch (Exception e)
{
e
printStackTrace () ;
}
}
public DAO(DataSource ds) {
this
ds = ds;
}
public void setDataSource(DataSource ds) {
this
ds = ds;
}
protected void close(ResultSet rs) {
if (rs != null) {
try {
rs
close();
} catch (SQLException e) {
}
rs = null;
}
}
protected void close(PreparedStatement pstmt) {
if (pstmt != null) {
try {
pstmt
close();
} catch (SQLException e) {
}
pstmt = null;
}
}
protected void close(Connection conn) {
if (conn != null) {
try {
conn
close();
} catch (SQLException e) {
e
printStackTrace();
}
conn = null;
}
}
protected void rollback(Connection conn) {
if (conn != null) {
try {
conn
rollback();
} catch (SQLException e) {
e
printStackTrace();
}
conn = null;
}
}
}
這個類主要是通過子類傳進來的先進結果集
取得查詢的記錄總數
並對數據庫連接進行簡單的管理
)
對數據庫進行訪問
CertificateDAO
java
java代碼:
代碼
package com
xindeco
business;
import java
io
*;
import java
sql
*;
import java
util
*;
import javax
sql
*;
import mon
dbconn
DbConn;
public class CertificateDAO extends DAO
{
public NationDAO(DataSource ds) {
super(ds);
}
public List findCertificateList(int offset
int limit) throws SQLException
{
int countRows =
;
ArrayList list = null ;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
conn = ds
getConnection();
String sql =
SELECT certificateID
certificateCode
certificateName
photoURL
+
description
graduateID FROM TCertificate
;
pstmt = conn
prepareStatement(sql);
rs = pstmt
executeQuery();
/*對游標進行處理
rsHandler 方法在父類DAO中*/
this
rsHandler(rs
offset
limit);
if (rs != null && rs
next ())
{
list = new ArrayList () ;
do
{
countRows++ ;
list
add (rs
VO (rs)) ;
}
while ( (countRows++ < limit) && rs
next ()) ;
}
close(rs);
close(pstmt);
} catch (SQLException e) {
close(rs);
close(pstmt);
rollback(conn);
e
printStackTrace();
}
finally {
close(conn);
}
return list ;
}
private CertificateVO rs
VO (ResultSet rs)
{
try
{
CertificateVO certificateVO = new CertificateVO () ;
certificateVO
setCertificateID (rs
getInt (
certificateID
)) ;
certificateVO
setCertificateCode (rs
getString (
certificateCode
)) ;
certificateVO
setCertificateName (rs
getString (
certificateName
)) ;
certificateVO
setPhotoURL (rs
getString (
photoURL
)) ;
certificateVO
setDescription (rs
getString (
description
)) ;
certificateVO
setGraduateID (rs
getInt (
graduateID
)) ;
return certificateVO ;
}
catch (Exception ex)
{
ex
printStackTrace () ;
return null ;
}
}
}
findCertificateList(int offset
int limit)是查得所有要顯示的數據
並放入ArrayList中
看過網上有些例子
把數據記錄放入ArrayList的動作過程直接在while循環體裡完成
如果字段多的話
會造成方法過於寵大
又不美觀
這裡
數據記錄放入ArrayList的動作過程由rs
VO方法完成
就比較整潔了
另外
if (rs != null && rs
next ()) 配合while ( (countRows++ < limit) && rs
next ()) 是為了程序的健壯性考慮的
稍分析一下不難得出結論
建立控制器組件
CertificateAction
java
java代碼:
代碼
package com
xindeco
presentation;
import javax
sql
* ;
import java
util
* ;
import javax
servlet
http
* ;
import javax
servlet
* ;
import org
apache
struts
action
* ;
import org
apache
struts
util
* ;
import mon
Pager;
import com
xindeco
business
graduatedata
CertificateDAO ;
public class CertificateAction
extends Action
{
private static final int PAGE_LENGTH =
; //每頁顯示
條記錄
public ActionForward execute (ActionMapping mapping
Actionform form
HttpServletRequest request
HttpServletResponse response)
{
ActionForward myforward = null ;
String myaction = mapping
getParameter () ;
if (isCancelled (request))
{
return mapping
findForward (
failure
) ;
}
if (
equalsIgnoreCase (myaction))
{
myforward = mapping
findForward (
failure
) ;
}
else if (
LIST
equalsIgnoreCase (myaction))
{
myforward = performList (mapping
form
request
response) ;
}
else
{
myforward = mapping
findForward (
failure
) ;
}
return myforward ;
}
private ActionForward performList (ActionMapping mapping
Actionform actionform
HttpServletRequest request
HttpServletResponse response)
{
try
{
DataSource ds = (DataSource) servlet
getServletContext()
getAttribute(Action
DATA_SOURCE_KEY);
CertificateDAO certificateDAO = new CertificateDAO (ds) ;
int offset =
; //翻頁時的起始記錄所在游標
int length = PAGE_LENGTH;
String pageOffset = request
getParameter(
pager
offset
);
if (pageOffset == null || pageOffset
equals(
)) {
offset =
;
} else {
offset = Integer
parseInt(pageOffset);
}
List certificateList = certificateDAO
findCertificateList (offset
length) ;
int size = certificateDAO
getRows(); // 取得總記錄數
String url = request
getContextPath()+
/
+mapping
getPath()+
do
;
String pagerHeader = Pager
generate(offset
size
length
url); //分頁處理
request
setAttribute (
pager
pagerHeader) ;
request
setAttribute (
list
certificateList) ;
}
catch (Exception e)
{
e
printStackTrace();
return mapping
findForward (
error
) ;
}
return mapping
findForward (
success
) ;
}
}
CertificateAction
java主要是把數據從DAO中取出
並放入一個ArrayList 中
然後通過配置文件再軟件View的JSP頁
建立視圖listcertificate
jsp文件
jsp代碼:
代碼
<%@ page contentType=
text/html; charset=GBK
%>
<%@ taglib uri=
/WEB
INF/struts
template
tld
prefix=
template
%>
<%@ taglib uri=
/WEB
INF/struts
html
tld
prefix=
html
%>
<%@ taglib uri=
/WEB
INF/struts
bean
tld
prefix=
bean
%>
<%@ taglib uri=
/WEB
INF/struts
logic
tld
prefix=
logic
%>
<table bgcolor=
#
cellpadding=
cellspacing=
border=
width=
>
<tr>
<td>
<table cellpadding=
cellspacing=
border=
width=
>
<tr>
<td bgcolor=
#fecc
>&</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table cellpadding=
cellspacing=
border=
width=
>
<tr>
<td bgcolor=
#d
e
ed
>
&&<bean:message key=
label
list
certificate
/>
</td>
</tr>
<tr bgcolor=
#FFFFFF
>
<td width=
%
></td><td width=
%
></td><td width=
%
></td>
</tr>
<tr>
<td>
<table bgcolor=
#f
f
f
width=
cellspacing=
border=
>
<tr bgcolor=
#bacce
>
<td><b><bean:message key=
Certificate
select
/> </b></td>
<td><b><bean:message key=
Certificate
certificateID
/> </b></td>
<td><b><bean:message key=
Certificate
certificateCode
/></b></td>
<td><b><bean:message key=
Certificate
certificateName
/></b></td>
<td><b><bean:message key=
Certificate
view
/></b></td>
</tr>
<bean:write name=
pager
property=
description
/>
<logic:equal name=
pager
property=
hasPrevious
value=
true
>
<a /graduatedata/list
do?viewPage=<bean:write name=
pager
property=
previousPage
/>
class=
a
>
Previous
</a>
</logic:equal>
<logic:equal name=
pager
property=
hasNext
value=
true
>
<a /graduatedata/list
do?viewPage=<bean:write name=
pager
property=
nextPage
/>
class=
a
>
Next
</a>
</logic:equal>
<logic:notEmpty name=
list
scope=
request
>
<logic:iterate id=
certificate
name=
list
type=
com
xindeco
business
graduatedata
CertificateVO
scope=
request
>
<tr bgcolor=
#FFFFFF
>
<td><html:text property=
name
value=
<bean:write name=
certificate
property=
certificateID
scope=
page
/>
/>
</td>
<td> <bean:write name=
certificate
property=
certificateID
scope=
page
/></td>
<td> <bean:write name=
certificate
property=
certificateCode
scope=
page
/></td>
<td> <bean:write name=
certificate
property=
certificateName
scope=
page
/></td>
<td> <bean:write name=
certificate
property=
photoURL
scope=
page
/></td>
</tr>
</logic:iterate>
</logic:notEmpty>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
對應的配置文件struts
config
xml
java代碼:
代碼
<?xml version=
encoding=
UTF
?>
<!DOCTYPE struts
config PUBLIC
//Apache Software Foundation//DTD Struts Configuration
//EN
config_
_
dtd
>
<struts
config>
<form
beans>
<form
bean name=
certificateform
type=
com
xindeco
presentation
graduatedata
Certificateform
/>
</form
beans>
<global
forwards>
<forward name=
error
path=
/error/error
jsp
/>
</global
forwards>
<action
mappings>
<action name=
certificateform
parameter=
LIST
path=
/graduatedata/list
scope=
request
type=
com
xindeco
presentation
graduatedata
CertificateAction
validate=
true
>
<forward name=
success
path=
/graduatedata/listcertificate
jsp
/>
</action>
</action
mappings>
……
</struts
config>
最後當然是最重要的分頁代碼了
Pager
java
java代碼:
代碼
package mon;
import java
util
* ;
public class Pager {
private static int MAX_PAGE_INDEX =
; //頁腳顯示多少頁
private static String HEADER =
Result page
;
public static String generate(int offset
int length
int size
String url) {
if (length > size) {
String pref;
if (url
indexOf(
?
) >
) {
pref =
&
;
} else {
pref =
?
;
}
String header =
<font face=
Helvetica
size=
>
+HEADER+
:
;
if (offset >
) {
header +=
&<a href=\
+url+pref+
pager
offset=
+(offset
size)+
\
>[<< Prev]</a>\n
;
}
int start;
int radius = MAX_PAGE_INDEX/
*size;
if (offset < radius) {
start =
;
} else if(offset < length
radius) {
start = offset
radius;
} else {
start = (length/size
MAX_PAGE_INDEX)*size;
}
for(int i=start;i<length && i < start + MAX_PAGE_INDEX*size;i+=size) {
if (i == offset) {
header +=
<b>
+(i/size+
)+
</b>\n
;
} else {
header +=
&<a href=\
+url+pref+
pager
offset=
+i+
\
>
+(i/size+
)+
</a>\n
;
}
}
if(offset < length
size) {
header +=
&<a href=\
+url+pref+
pager
offset=
+((int)offset+(int)size)+
\
>[Next >>]</a>\n
;
}
header +=
</font>
;
return header;
} else {
return
;
}
}
}
這部分代碼的實現相當簡潔
但已經足夠完成所需了
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28498.html