分享
 
 
 

一个高效简洁的Struts分页方法

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

在网上看了几个Structs分页,感觉不是很完善,于是根据自己的经验,写了一个相对高效简洁的分页方法。由于本人水平有限,如果大家有什么更好的想法,欢迎不吝赐教。

一、 开发环境

我的开发环境是:JBuilder x + Weblogic 8.1 + Oracle 9i + Windows 2003 ,如果朋友们的开发环境不一样亦无妨。

二、开发思路

既然讲的是Struts,那自然离不了MVC,分页显示也是如此。

1、 建立数据库和对应的表,本例的表是TCertificate。

2、 建立适当的模型组件,对应你要查询数据库中的表。这部分由DAO数据访问层来实现,如果有的朋友对DAO不熟悉可以查询一下相关资料。本例由CertificateDAO.java来实现。

3 、建立分页所需要的模型组件,由javaBean来充当,并与CertificateDAO实现分离。网上介绍的很多方法,都存在着数据与分页组件藕合的现象,这也是本方法与其它分页方法的主要不同之处。

4、建立控制器组件,这部分由Struts 中的Action来实现。主要负责将实例化CertificateDAO,只取要显示的数据记录,存入ArrayList对象然后返回,并放到request中。而分页部分则根据分页条件,单独进行构造,避免了与DAO混在一起的情况发生。网上其它介绍的一些分页方法中,基本上都是一次性读出所有查询的数据,然后再由分页相关组件进行构造。这样,如果数据量大的话,很容易形成瓶颈。在本例中由于不是一次性地读出查询的所有数据,而只是读出一个页面要显示的数据记录,这就节省了很多不必要的数据传输,提高了效率。本例中为CertificateAction.java。

5、建立视图组件,这部分由jsp来充当,为了不出现java 代码,我们使用Struts提供的标签库,主要负责从request中取出刚刚放入的对象,通过反复调用CertificateAction以及action参数,而实现分页显示。本例中为listcertificate.jsp。

6、 建立并配置struts-config.xml。

三、实例代码

确定好上面的开发思路后,代码的实现就有单可循了。

1、建数据库和相应的表。

2、数据逻辑层的相关代码。

1)、通用的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 org.apache.commons.beanutils.BeanUtils;

public class DAO

{

protected DataSource ds;

/**

* 说明:取得当前查询的总记录数

*/

public int getRows ()

{

return this.count;

}

public void rsHandler (ResultSet rs, int offset, int limit)

{

try

{

count = 0;

rs.absolute ( -1) ;

count = rs.getRow () ;

if (offset <= 0)

{

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;

}

}

}

这个类主要是通过子类传进来的先进结果集,取得查询的记录总数,并对数据库连接进行简单的管理。

2)、对数据库进行访问:CertificateDAO.java

java代码:

代码:

--------------------------------------------------------------------------------

package com.xindeco.business;

import java.io.*;

import java.sql.*;

import java.util.*;

import javax.sql.*;

import com.xindeco.common.dbconn.DbConn;

public class CertificateDAO extends DAO

{

public NationDAO(DataSource ds) {

super(ds);

}

public List findCertificateList(int offset,int limit) throws SQLException

{

int countRows = 0 ;

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 (rs2VO (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 rs2VO (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的动作过程由rs2VO方法完成,就比较整洁了。另外,if (rs != null && rs.next ()) 配合while ( (countRows++ < limit) && rs.next ()) 是为了程序的健壮性考虑的,稍分析一下不难得出结论。

3、建立控制器组件: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 com.xindeco.common.Pager;

import com.xindeco.business.graduatedata.CertificateDAO ;

public class CertificateAction

extends Action

{

private static final int PAGE_LENGTH = 5 ; //每页显示5条记录

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 = 0; //翻页时的起始记录所在游标

int length = PAGE_LENGTH;

String pageOffset = request.getParameter("pager.offset");

if (pageOffset == null || pageOffset.equals("")) {

offset = 0;

} 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 (Except

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有