在网上看了几个Structs分页感觉不是很完善于是根据自己的经验写了一个相对高效简洁的分页方法由于本人水平有限如果大家有什么更好的想法欢迎不吝赐教
一 开发环境
我的开发环境是JBuilder x + Weblogic + Oracle i + Windows 如果朋友们的开发环境不一样亦无妨
二开发思路
既然讲的是Struts那自然离不了MVC分页显示也是如此
建立数据库和对应的表本例的表是TCertificate
建立适当的模型组件对应你要查询数据库中的表这部分由DAO数据访问层来实现如果有的朋友对DAO不熟悉可以查询一下相关资料本例由CertificateDAOjava来实现
建立分页所需要的模型组件由javaBean来充当并与CertificateDAO实现分离网上介绍的很多方法都存在着数据与分页组件藕合的现象这也是本方法与其它分页方法的主要不同之处
建立控制器组件这部分由Struts 中的Action来实现主要负责将实例化CertificateDAO只取要显示的数据记录存入ArrayList对象然后返回并放到request中而分页部分则根据分页条件单独进行构造避免了与DAO混在一起的情况发生网上其它介绍的一些分页方法中基本上都是一次性读出所有查询的数据然后再由分页相关组件进行构造这样如果数据量大的话很容易形成瓶颈在本例中由于不是一次性地读出查询的所有数据而只是读出一个页面要显示的数据记录这就节省了很多不必要的数据传输提高了效率本例中为CertificateActionjava
建立视图组件这部分由jsp来充当为了不出现java 代码我们使用Struts提供的标签库主要负责从request中取出刚刚放入的对象通过反复调用CertificateAction以及action参数而实现分页显示本例中为listcertificatejsp
建立并配置strutsconfigxml
三实例代码
确定好上面的开发思路后代码的实现就有单可循了
建数据库和相应的表
数据逻辑层的相关代码
)通用的DAO类CommonDAOjava
这是一个很多DAO都要继承到的通用DAO类是我根据实践总结出来的为了减少篇幅这里只显示和本例相关的代码
java代码:
代码
package comxindecobusiness ;
import javaio*;
import javasql*;
import javautil*;
import javaxsql*;
import javalangIllegalAccessException;
import javalangreflectInvocationTargetException;
import monsbeanutilsBeanUtils;
public class DAO
{
protected DataSource ds;
/**
* 说明:取得当前查询的总记录数
*/
public int getRows ()
{
return unt;
}
public void rsHandler (ResultSet rs int offset int limit)
{
try
{
count = ;
rsabsolute ( ) ;
count = rsgetRow () ;
if (offset <= )
{
rsbeforeFirst () ;
}
else
{
rsabsolute (offset) ;
}
}
catch (Exception e)
{
eprintStackTrace () ;
}
}
public DAO(DataSource ds) {
thisds = ds;
}
public void setDataSource(DataSource ds) {
thisds = ds;
}
protected void close(ResultSet rs) {
if (rs != null) {
try {
rsclose();
} catch (SQLException e) {
}
rs = null;
}
}
protected void close(PreparedStatement pstmt) {
if (pstmt != null) {
try {
pstmtclose();
} catch (SQLException e) {
}
pstmt = null;
}
}
protected void close(Connection conn) {
if (conn != null) {
try {
connclose();
} catch (SQLException e) {
eprintStackTrace();
}
conn = null;
}
}
protected void rollback(Connection conn) {
if (conn != null) {
try {
connrollback();
} catch (SQLException e) {
eprintStackTrace();
}
conn = null;
}
}
}
这个类主要是通过子类传进来的先进结果集取得查询的记录总数并对数据库连接进行简单的管理
)对数据库进行访问CertificateDAOjava
java代码:
代码
package comxindecobusiness;
import javaio*;
import javasql*;
import javautil*;
import javaxsql*;
import mondbconnDbConn;
public class CertificateDAO extends DAO
{
public NationDAO(DataSource ds) {
super(ds);
}
public List findCertificateList(int offsetint limit) throws SQLException
{
int countRows = ;
ArrayList list = null ;
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
conn = dsgetConnection();
String sql =
SELECT certificateID certificateCodecertificateNamephotoURL
+ descriptiongraduateID FROM TCertificate ;
pstmt = connprepareStatement(sql);
rs = pstmtexecuteQuery();
/*对游标进行处理rsHandler 方法在父类DAO中*/
thisrsHandler(rsoffsetlimit);
if (rs != null && rsnext ())
{
list = new ArrayList () ;
do
{
countRows++ ;
listadd (rsVO (rs)) ;
}
while ( (countRows++ < limit) && rsnext ()) ;
}
close(rs);
close(pstmt);
} catch (SQLException e) {
close(rs);
close(pstmt);
rollback(conn);
eprintStackTrace();
}
finally {
close(conn);
}
return list ;
}
private CertificateVO rsVO (ResultSet rs)
{
try
{
CertificateVO certificateVO = new CertificateVO () ;
certificateVOsetCertificateID (rsgetInt (certificateID)) ;
certificateVOsetCertificateCode (rsgetString (certificateCode)) ;
certificateVOsetCertificateName (rsgetString (certificateName)) ;
certificateVOsetPhotoURL (rsgetString (photoURL)) ;
certificateVOsetDescription (rsgetString (description)) ;
certificateVOsetGraduateID (rsgetInt (graduateID)) ;
return certificateVO ;
}
catch (Exception ex)
{
exprintStackTrace () ;
return null ;
}
}
}
findCertificateList(int offsetint limit)是查得所有要显示的数据并放入ArrayList中看过网上有些例子把数据记录放入ArrayList的动作过程直接在while循环体里完成如果字段多的话会造成方法过于宠大又不美观 这里数据记录放入ArrayList的动作过程由rsVO方法完成就比较整洁了另外if (rs != null && rsnext ()) 配合while ( (countRows++ < limit) && rsnext ()) 是为了程序的健壮性考虑的稍分析一下不难得出结论
建立控制器组件CertificateActionjava
java代码:
代码
package comxindecopresentation;
import javaxsql* ;
import javautil* ;
import javaxservlethttp* ;
import javaxservlet* ;
import orgapachestrutsaction* ;
import orgapachestrutsutil* ;
import monPager;
import comxindecobusinessgraduatedataCertificateDAO ;
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 = mappinggetParameter () ;
if (isCancelled (request))
{
return mappingfindForward (failure) ;
}
if (equalsIgnoreCase (myaction))
{
myforward = mappingfindForward (failure) ;
}
else if(LISTequalsIgnoreCase (myaction))
{
myforward = performList (mapping form request response) ;
}
else
{
myforward = mappingfindForward (failure) ;
}
return myforward ;
}
private ActionForward performList (ActionMapping mapping
Actionform actionform
HttpServletRequest request
HttpServletResponse response)
{
try
{
DataSource ds = (DataSource) servletgetServletContext()getAttribute(ActionDATA_SOURCE_KEY);
CertificateDAO certificateDAO= new CertificateDAO(ds) ;
int offset = ; //翻页时的起始记录所在游标
int length = PAGE_LENGTH;
String pageOffset = requestgetParameter(pageroffset);
if (pageOffset == null || pageOffsetequals()) {
offset = ;
} else {
offset = IntegerparseInt(pageOffset);
}
List certificateList = certificateDAO findCertificateList (offsetlength) ;
int size = certificateDAOgetRows(); //取得总记录数
String url = requestgetContextPath()+/+mappinggetPath()+do;
String pagerHeader = Pagergenerate(offset size length url); //分页处理
requestsetAttribute (pager pagerHeader) ;
requestsetAttribute (list certificateList) ;
}
catch (Exception e)
{
eprintStackTrace();
return mappingfindForward (error) ;
}
return mappingfindForward (success) ;
}
}
CertificateActionjava主要是把数据从DAO中取出并放入一个ArrayList 中然后通过配置文件再软件View的JSP页
建立视图listcertificatejsp文件
jsp代码:
代码
<%@ page contentType=text/html; charset=GBK %>
<%@ taglib uri=/WEBINF/strutstemplatetld prefix=template %>
<%@ taglib uri=/WEBINF/strutshtmltld prefix=html %>
<%@ taglib uri=/WEBINF/strutsbeantld prefix=bean %>
<%@ taglib uri=/WEBINF/strutslogictld 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=#deed>
&&<bean:message key=labellistcertificate/>
</td>
</tr>
<tr bgcolor=#FFFFFF>
<td width=%></td><td width=%></td><td width=%></td>
</tr>
<tr>
<td>
<table bgcolor=#fff width= cellspacing= border=>
<tr bgcolor=#bacce>
<td><b><bean:message key=Certificateselect/> </b></td>
<td><b><bean:message key=CertificatecertificateID/> </b></td>
<td><b><bean:message key=CertificatecertificateCode/></b></td>
<td><b><bean:message key=CertificatecertificateName/></b></td>
<td><b><bean:message key=Certificateview/></b></td>
</tr>
<bean:write name=pager property=description/>
<logic:equal name=pager property=hasPrevious value=true>
<a /graduatedata/listdo?viewPage=<bean:write name=pager property=previousPage/> class=a>
Previous
</a>
</logic:equal>
<logic:equal name=pager property=hasNext value=true>
<a /graduatedata/listdo?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=comxindecobusinessgraduatedataCertificateVOscope=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>
对应的配置文件strutsconfigxml
java代码:
代码
<?xml version= encoding=UTF?>
<!DOCTYPE strutsconfig PUBLIC //Apache Software Foundation//DTD Struts Configuration //EN config__dtd>
<strutsconfig>
<formbeans>
<formbean name=certificateform type=comxindecopresentationgraduatedataCertificateform />
</formbeans>
<globalforwards>
<forward name=error path=/error/errorjsp />
</globalforwards>
<actionmappings>
<action name=certificateform parameter=LIST path=/graduatedata/list scope=request type=comxindecopresentationgraduatedataCertificateAction validate=true>
<forward name=success path=/graduatedata/listcertificatejsp />
</action>
</actionmappings>
……
</strutsconfig>
最后当然是最重要的分页代码了Pagerjava
java代码:
代码
package mon;
import javautil* ;
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 (urlindexOf(?) > ) {
pref = &;
} else {
pref = ?;
}
String header = <font face=Helvetica size=>+HEADER+: ;
if (offset > ) {
header += &<a href=\+url+pref+pageroffset=+(offsetsize)+\>[<< Prev]</a>\n;
}
int start;
int radius = MAX_PAGE_INDEX/*size;
if (offset < radius) {
start = ;
} else if(offset < lengthradius) {
start = offset radius;
} else {
start = (length/sizeMAX_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+pageroffset=+i+\>+(i/size+)+</a>\n;
}
}
if(offset < length size) {
header += &<a href=\+url+pref+pageroffset=+((int)offset+(int)size)+\>[Next >>]</a>\n;
}
header += </font>;
return header;
} else {
return ;
}
}
}
这部分代码的实现相当简洁但已经足够完成所需了