一、
开发环境
我的开发环境是:
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++
}
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 (Exception e)
{
e.printStackTrace();
return mapping.findForward ("error") ;
}
return mapping.findForward ("success") ;
}
}
CertificateAction.java
主要是把数据从
DAO
中取出,并放入一个
ArrayList
中,然后通过配置文件再软件
View
的
JSP
页。
5
、建立视图
listcertificate.jsp
文件。
jsp
代码
:
代码:
--------------------------------------------------------------------------------
| |||||||||||||||
|
6
、对应的配置文件
struts-config.xml
。
java
代码
:
代码:
--------------------------------------------------------------------------------
struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "" target="_blank">http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
……
7
、最后当然是最重要的分页代码了:
Pager.java
java
代码
:
代码:
--------------------------------------------------------------------------------
package com.xindeco.common;
import java.util.* ;
public class Pager {
private static int MAX_PAGE_INDEX = 10; //
页脚显示多少页
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("?") > -1) {
pref = "&";
} else {
pref = "?";
}
String header = "" + HEADER + ": ";
if (offset > 0) {
header += "&
+ (offset - size) + "\">[<\n";
}
int start;
int radius = MAX_PAGE_INDEX / 2 * size;
if (offset
start = 0;
} else if (offset
start = offset - radius;
} else {
start = (length / size - MAX_PAGE_INDEX) * size;
}
for (int i = start; i
if (i == offset) {
header += "" + (i / size + 1) + "\n";
} else {
header += "&
\n";}
}
if (offset
header += "&
\n";}
header += "";
return header;
} else {
return "";
}
}
}
这部分代码的实现相当简洁,但已经足够完成所需了。
posted on 2007-08-06 14:13 蛮哥♂枫 阅读(2620) 评论(1) 编辑 收藏 所属分类: Java