分页参考1

azaFighting 2007-09-30 12:33:22
既然讲的是 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,"

   + "des.c.r.i.p.tion,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.setDes.c.r.i.p.tion (rs.getString ("des.c.r.i.p.tion")) ;

   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 ()) 是为了程序的健壮性考虑的,稍分析一下不难得出结论。

...全文
66 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
帮你顶一下

针对这个分页,我还有些小意见:

在数据库层将满足条件的数据全部取出,扔给 Web 层,让 Web 层利用游标去选取需要的页数,再把大部分的扔掉!而且每翻一页都得重新做一遍这样的事情,加之还使用了游标移行,如果数据结果集是庞大的话,这样做会损失性能的。

一般来说,像大数量的分页,是采用分页的 SQL 语句,也就是需要第几页数据,就直接从数据库中取出当前页的数据行,因为没有冗余的数据,这样在数据处理和传输方面都是很高效的。当然了,这样对数据库服务器造成的压力也是可想而知的,每翻一页都得跟数据库打一次交道,如果做得更好的话,可以从数据库中取出多页的数据,缓存起来,显示当前页的数据,翻页时如果缓存中有该页的数据,则从缓存里取,没有的话,再向数据库去要。

但是要采用分页 SQL 语句的话,也是很麻烦的,像 MS SQL Server、Oracle、MySQL 之类的数据库实现方式都不是一样的,以 MySQL 最为简单,SQL Server 最为麻烦(特别是使用到多表联接查询的时候)。像 Hibernate 实现这样的分页,其关键就在于配置了所使用的数据库方言,根据不同的数据库采用不同的 SQL 语句。

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧