熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

一個高效簡潔的Struts分頁方法

2013-11-23 20:26:12  來源: Java開源技術 

  在網上看了幾個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 ;
  }
  }
  }
  
  這部分代碼的實現相當簡潔但已經足夠完成所需了
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28498.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.