`
bibiye
  • 浏览: 172017 次
社区版块
存档分类
最新评论

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

阅读更多

    在网上看了几个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 (Exception e)
                {
                        e.printStackTrace();
                        return mapping.findForward ("error") ;
                }
                return mapping.findForward ("success") ;
        }
}


CertificateAction.java主要是把数据从DAO中取出,并放入一个ArrayList 中,然后通过配置文件再软件View的JSP页。

5、建立视图listcertificate.jsp文件。

java代码:

<%@ 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="#666666" cellpadding="1" cellspacing="0" border="0" width="500">
<tr>
<td>
<table cellpadding="0" cellspacing="0" border="0" width="500">
<tr>
<td bgcolor="#fecc51">&</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table cellpadding="0" cellspacing="0" border="0" width="500">
  <tr>
<td bgcolor="#d6e0ed">
    &&<bean:message key="label.list4certificate"/>
  </td>
</tr>
<tr bgcolor="#FFFFFF">
<td width="5%"></td><td width="19%"></td><td width="76%"></td>
</tr>
    <tr>
<td>
<table bgcolor="#f2f2f2" width="500" cellspacing="0" border="0">
      <tr bgcolor="#bacce1">
        <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 href="/graduatedata/list.do?viewPage=<bean:write name="pager" property="previousPage"/>" class="a02">
           Previous
        </a>
  </logic:equal>
  <logic:equal name="pager" property="hasNext" value="true">
    ?a href="/graduatedata/list.do?viewPage=<bean:write name="pager" property="nextPage"/>" class="a02">
     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>

6、对应的配置文件struts-config.xml。

java代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.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>

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 = "<font face='Helvetica' size='-1'>"+HEADER+": ";
          if (offset > 0) {
                header += "&<a href=\""+url+pref+"pager.offset="+(offset-size)+"\">[<< Prev]</a>\n";
          }
          int start;
          int radius = MAX_PAGE_INDEX/2*size;
          if (offset < radius) {
                start = 0;
          } 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+1)+"</b>\n";
                } else {
                  header += "&<a href=\""+url+pref+"pager.offset="+i+"\">"+(i/size+1)+"</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 "";
        }
  }
}

这部分代码的实现相当简洁,但已经足够完成所需了。

分享到:
评论
2 楼 bibiye 2009-08-17  
可以啊,这篇文章太老了,其实有很多开源可以用的,像EC/Display呵呵~
1 楼 gs80140 2009-08-10  
这样还是有些繁呀.能不能做得更简洁一些.比如说:在jsp页面里面加入一个组件,只负责向Action传送当前要显示的页数.而Action负责向该组件传送当前页数和总页数呢?

相关推荐

    高效struts分页算法

    Struts分页算法是Web应用开发中的重要组成部分,特别是在大型数据集展示时,为了提高用户体验,需要将数据分页展示。本算法遵循Model-View-Controller(MVC)设计模式,使得代码结构清晰,易于维护。 在Struts框架...

    jsp +struts 分页经典

    在Struts中,通常有一个专门的Action类处理插入操作,接收前端提交的数据,调用模型层的方法进行数据验证和持久化操作,如插入数据库。在JSP页面上,用户填写表单,提交后由Struts框架处理表单数据并调用相应的...

    struts分页,数据查询资料

    这个“struts分页,数据查询资料”可能包含了如何在Struts框架下实现高效、灵活的分页查询方法。 首先,Struts框架的核心是Action类,它是业务逻辑和视图之间的桥梁。在实现分页功能时,我们需要创建一个Action类,...

    struts分页源代码

    Action中可以包含一个方法来处理分页请求,比如`doPagination()`,该方法会根据用户请求的页码和每页记录数来调整`PageBean`的属性。 3. **服务层(Service)**:服务层处理实际的业务逻辑,例如从数据库中查询数据。...

    Struts2分页方法

    `NewPagerService`类提供了一个方法`getPager(String currentPage, String pagerMethod, int totalRows)`,用于根据当前页码和分页方法创建`NewPager`实例。虽然示例代码中没有完整展示该方法的具体实现,但可以推测...

    ajax+struts分页

    本项目是关于“Ajax+Struts”实现分页的一个实例,旨在利用这两种技术的优势,提供一个高效、动态且用户友好的分页解决方案。 首先,让我们来理解一下核心概念: 1. **Ajax(Asynchronous JavaScript and XML)**...

    使用struts实现分页

    Struts 是一个经典的Java ...通过以上这些步骤和知识点,我们可以构建一个完整的基于Struts的分页系统,提供高效、用户友好的数据浏览体验。在实际开发中,还可以根据项目需求进行定制和扩展,如添加搜索、排序等功能。

    struts分页jar包

    Struts分页jar包是一个专为Struts框架设计的组件,用于在Web应用程序中实现高效、便捷的分页功能。Struts是Apache软件基金会下的一个开源项目,它提供了一个MVC(模型-视图-控制器)架构,帮助开发者构建结构清晰、...

    struts2增删改查,struts2分页查询

    Struts2是Apache软件基金会的一个开源Web应用框架,它继承了Struts1的一些特性,并在此基础上进行了大量的改进和扩展,提供了一个更为灵活、强大的MVC(Model-View-Controller)架构实现。在Struts2中,增删改查...

    Hibernate+Struts分页的实现

    总结来说,"Hibernate+Struts分页的实现"涉及了如何利用Struts和Hibernate的优势,通过将页面实体和分页逻辑解耦,实现高效、灵活的分页功能。这种方法不仅可以提升应用性能,还能提高代码的可维护性和复用性。在...

    Struts2分页源码技术的应用

    Struts2分页源码技术是Web开发中一个重要的实践,尤其是在处理大数据量时,能够有效地提高用户体验,避免一次性加载过多数据导致页面响应慢。在本文中,我们将深入探讨Struts2分页技术的实现原理、应用方法以及与...

    struts2.0实现的数据分页实现及实现分页步骤

    Struts2.0 是一个流行的Java Web开发框架,它提供了一种组织和控制MVC(Model-View-Controller)架构的方式,使得开发者可以更高效地构建动态Web应用程序。数据分页是Web应用中常见的需求,特别是在处理大量数据时,...

    Struts分页

    Struts分页是一种在Web应用中实现数据展示的高效方式,尤其当数据量较大时,分页能够提高用户体验,避免一次性加载过多数据导致页面响应慢。Struts是Apache的一个开源框架,它主要用于构建基于Java EE的Web应用。...

    jquery java struts2 实现分页 非常好看的分页

    在IT行业中,分页是网页应用中不可或缺的功能,特别是在数据量较大的情况下,它能帮助用户更有效地浏览和管理信息。本教程将详细讲解如何利用jQuery、Java和Struts...这种架构可以提供一个既美观又高效的分页解决方案。

    hibernate+struts2分页代码

    【hibernate+struts2分页代码】是关于如何在Java Web开发...通过这个“hibernate+struts2分页视频”,开发者可以学习到如何结合这两个强大的框架实现高效且用户友好的数据分页功能,从而提升Web应用的性能和用户体验。

    hibernate+struts后台分页

    Hibernate是一个强大的Java持久化框架,它简化了与数据库的交互,而Struts则是一个用于构建MVC(模型-视图-控制器)架构的Web应用框架。结合这两者,我们可以创建出高效且可扩展的后台分页解决方案。 首先,让我们...

    struts2实现分页

    `&lt;s:bean&gt;` 是 Struts2 提供的一个用于创建 bean 实例的标签。它支持创建一个指定类的实例,并可以通过 `&lt;s:param&gt;` 子标签为这个 bean 设置参数。在分页实现中,我们主要利用 `&lt;s:bean&gt;` 创建 `org.apache.struts2....

Global site tag (gtag.js) - Google Analytics