论坛首页 Java企业应用论坛

Spring+Hibernate+Struts技术的一个分页程序,共享给大家

浏览 65910 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-07-19  
我用的是Spring+Hibernate+Struts框架:

这是我的DAO的核心代码
import org.springframework.orm.hibernate.support.HibernateDaoSupport;
// 用Spring支持的Hibernate方法,使Hibernate对数据库的操作继续瘦身
public List getOfficeBySearchCriteria(final String hsql,final int pageNo,final int page_size) throws DataAccessException // hsql 是如:"select office1 from Office as office1 order by office1.officename";pageNo 是第几页;page_size是每页记录数
{
String sql;
int total_count=0;
List offices=new ArrayList();
//offices= getHibernateTemplate().find("from Office office1 where office1.officename like ?", "%"+officeName+"%");
offices= getHibernateTemplate().find(hsql); //为了得到总记录数
total_count=offices.size();
crossPageInfo= crossPageBean.getCrossPageInfo(total_count,pageNo,page_size);

sql=hsql+ " limit " + (pageNo-1)*page_size + "," +page_size;
offices= getHibernateTemplate().find(sql); //为了得到页记录信息 System.out.println("The list offices size: "+offices.size());
return offices;
}

//其中crossPageBean.getCrossPageInfo只是得到页面的如:总页数、供多少页的信息等一般的翻页信息;

我在Action中是这样调用的
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception
{
CrossPageInfo crossPageInfo=new CrossPageInfo();
String hsql="select office1 from Office office1 order by office1.officename";
String pageNo=request.getParameter("pageNo");
int pageNoi=1;
if(pageNo==null)
   pageNo="1";
pageNoi=Integer.parseInt(pageNo);
int pageSize=5;
//List offices=getOfficeService().getAllOffice();
List offices=getOfficeService().getOfficeBySearchCriteria(hsql,pageNoi,pageSize);
crossPageInfo=getOfficeService().getCrossPageInfo();
System.out.println("The CorssPgaeInfo :"+crossPageInfo.getPageNo());
System.out.println(crossPageInfo.getPageSize());

request.setAttribute("offices",offices);
request.setAttribute("pageInfo",crossPageInfo);
return mapping.findForward("success");
//throw new UnsupportedOperationException("Generated method 'execute(...)' not implemented.");
}

//其中getOfficeService()只是提供接口服务的方法。


我的表现页面是这样的

<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<%@ taglib uri="/WEB-INF/struts-template.tld" prefix="template" %>
<%@ page import="com.uplus.util.CrossPageInfo"%>

<html>
<head>
<title>
mySearchCList
</title>

</head>
<body bgcolor="#ffffff">
<form name="form1" action="officesearch.do" method="post">
<table >
<tr>
<td>OfficeName:<input name="officeName" type="text"></td><td><input type="submit" name="sb" value="Search"></td>
</tr>
</table>
</form>
<br><a href="/jsp/office/officeadd.jsp">Add</a>

<table bgcolor="#DBE9F1" align="center"  class="InputFrameMain" style="MARGIN: 0px" cellSpacing="1" cellPadding="0"  BGALIGN="CENTER" BGVALIGn="middle" width="100%" VALIGN="middle" >
<tr><td align="center">OfficeName</td><td align="center">OfficePhone</td></tr>
<logic:iterate id="office" name="offices" > 
<tr bgcolor="#ffffff">
            <td align="center"><a href="officesee.do?id=<bean:write name='office' property='id'/>" target="_blank"><bean:write name="office" property="officename"/></a></td>
            <td align="center"><bean:write name="office" property="officephone"/></td>
            <td align="center"><a href="officeedit.do?id=<bean:write name='office' property='id'/>" >Update </a> 
            <td align="center"><a href="officedel.do?id=<bean:write name='office' property='id'/>" onclick="return confirm('Would You  Detele It? ')" >Delete </a> 
        </tr>
</logic:iterate>
</table>
<%CrossPageInfo cpInfo=(CrossPageInfo)request.getAttribute("pageInfo");%>

<table width="100%" align="center"   class="InputFrameMain" style="MARGIN: 0px" cellPadding="0" cellSpacing="0">
    <tr  ><form action="officelist.do" method="post"  onsubmit='return checkform2(this)'>
        <td width=70%>Total <font color="blue"><%=cpInfo.getTotalRow()%></font>&items found,Total&<font color="blue"><%=cpInfo.getTotalPage()%></font> Pages,Current No <font color="blue"><%=cpInfo.getPageNo()%> </font>Page.
Go to <input name="pageNo" type="text" size="5" class="input">Page
<input name="sb2" type="submit" class="button" value="Go">
</td></form>
<td width=30% align='left'>
<%if(cpInfo.getPageNo()>1){%>
&<a href="officelist.do?pageNo=1">
<%}%>First</a>
<%if(cpInfo.getPageNo()>1){ %>
&<a href="officelist.do?pageNo=<%=cpInfo.getPageNo()-1%>">
<%}%>Previous</a>
<%if(cpInfo.getPageNo()<cpInfo.getTotalPage()){ %>
&<a href="officelist.do?pageNo=<%=cpInfo.getPageNo()+1%>">
<%}%>Next</a>
<%if(cpInfo.getTotalPage()>cpInfo.getPageNo()){%>
&<a href="officelist.do?pageNo=<%=cpInfo.getTotalPage()%>">
<%}%>Last</a></td>
    </tr>

</table>
</body>
</html>


大家可以看一下我的处理过程,其中在DAO里为了得到总计录数执行了一次次数据表查询HSQL;得到数据又执行了一次HSQL,我觉得这样好像有些不太好,大家觉得怎样?大家提出宝贵的意见吧!
   发表时间:2004-07-21  
我的方法是第一次使用分页处理时,统计出分页的数据,如总记录数、页数等,以后查询分页的话就不统计这些了,这样每次分页查询需要执行的操作基本上就是一次hibernate调用(注意不同分页模块的相互处理就可以了)

而且取分页数据我采用的query,他自己支持分页,一般的应用都能满足

感觉比直接用jdbc分页要慢一些,我的统计数据基本上是要慢50~100ms的样子,不过没关系
0 请登录后投票
   发表时间:2004-07-24  
如果换成webwork2就更简单了
0 请登录后投票
   发表时间:2004-07-30  
需要改进:
hsql="select office1 from Office as office1 order by office1.officename"
有两处不好的:
1,实际查出了符合条件的所有po,多么的浪费资源
2,查总记录根本不需要order by这种影响性能的多余的clause

改成"select count(id) from Office where ..."
用query().iterate().next()得到总记录数

另外,分页,hibernate有了相应的包装,不需要你进行这样的sql构造:
sql=hsql+ " limit " + (pageNo-1)*page_size + "," +page_size;
0 请登录后投票
   发表时间:2004-07-30  
首先感谢sorphi的建议。

我的DAO的核心代码改为:

public List getOfficeBySearchCriteria(final String hsql,final int pageNo,final int page_size) throws Exception
{
Session session=getSession();
String sql;
int total_count=0;
int pageNog=1;
total_count=getTotalCount(session,hsql);
//System.out.println("The counts :"+total_count);
List offices=new ArrayList();
crossPageInfo= crossPageBean.getCrossPageInfo(total_count,pageNo,page_size);
pageNog=pageNo;
if(crossPageInfo.getTotalPage()<pageNo)pageNog=crossPageInfo.getTotalPage();
if(pageNo<1)pageNog=1;

// sql=hsql+ " limit " + (pageNog-1)*page_size + "," +page_size;
// offices= getHibernateTemplate().find(sql);
//被屏蔽掉的是原来的处理


    //以下是改过的处理方法
    Query query=null;
    query=session.createQuery(hsql);
    int start=(pageNog-1)*page_size;
    int rowNum=page_size;
query.setFirstResult(start);
query.setMaxResults(rowNum);
offices = query.list();

return offices;
}


public static int getTotalCount(Session session, String hql) throws Exception
{
  Integer amount = new Integer(0);
  int sql_from = hql.indexOf(" from");
  int sql_orderby=hql.indexOf("order by");//为了改进
  String countStr="";
  if(sql_orderby>0)
  {
      countStr="select count(*) "+hql.substring(sql_from,sql_orderby);
  }
  else
    countStr = "select count(*) "+hql.substring(sql_from);
 
  Query query = session.createQuery(countStr);
  if(!query.list().isEmpty()){
amount = (Integer) query.list().get(0);
  }
  else
  return 0;
      
  return amount.intValue();
   }

以下是我的总结:
1、用原来的方法处理(我用的是mysql数据库)——
sql=hsql+ " limit " + (pageNog-1)*page_size + "," +page_size;  //pageNog=5, page_size=5
offices= getHibernateTemplate().find(sql);

后台显示:
Hibernate: select office0_.id as id, office0_.officename as officename, office0_
.broker_id as broker_id, office0_.address_id as address_id, office0_.officephone
as officeph5_, office0_.officephone2 as officeph6_, office0_.fax as fax, office
0_.updatedate as updatedate from office office0_ where (office0_.officename like
'%%' ) order by  office0_.id desc limit 20 , 5


2、用现在的方法处理——
Query query=null;
query=session.createQuery(hsql);
int start=(pageNog-1)*page_size;
int rowNum=page_size;
query.setFirstResult(start);
query.setMaxResults(rowNum);
offices = query.list();



后台显示:
Hibernate: select office0_.id as id, office0_.officename as officename, office0_
.broker_id as broker_id, office0_.address_id as address_id, office0_.officephone
as officeph5_, office0_.officephone2 as officeph6_, office0_.fax as fax, office
0_.updatedate as updatedate from office office0_ where (office0_.officename like
'%%' ) order by  office0_.id desc limit ?

由此大家可以看出在运行效率两种方法是几乎相当的!不知大家的意见是怎样的?
0 请登录后投票
   发表时间:2005-06-17  
你这种方法在简单的HQL下没有问题。包含嵌套HQL,例如Select clause中Order By的sub select, 肯定出错。最安全的办法是重新写一个count sql。
0 请登录后投票
   发表时间:2005-06-17  
你的getTotalCount方法是有漏洞的,建议你分几个case,保证程序的General.比如,有没有子查询的判断,并且加入override的方法,让invoker直接提供count sql。
0 请登录后投票
   发表时间:2005-06-17  
谢谢大家的建议,我好久没有来了

有时间我再研究研究吧!
0 请登录后投票
   发表时间:2005-11-02  
今天有时间来了,我后来作了改进
我的DAO的核心代码改为:

public List getOfficeBySearchCriteria(final String hsql,final int pageNo,final int page_size); throws Exception 
{ 
Session session=getSession();; 
String sql; 
int total_count=0; 
int pageNog=1; 
//total_count=getTotalCount(session,hsql);; 
//System.out.println("The counts :"+total_count);; 
List offices=new ArrayList();; 
//crossPageInfo= crossPageBean.getCrossPageInfo total_count,pageNo,page_size);; 
//pageNog=pageNo; 
if(crossPageInfo.getTotalPage();<pageNo);pageNog=crossPageInfo.getTotalPage();; 
if(pageNo<1);pageNog=1; 

// sql=hsql+ " limit " + (pageNog-1);*page_size + "," +page_size; 
// offices= getHibernateTemplate();.find(sql);; 
//被屏蔽掉的是原来的处理 


//以下是改过的处理方法 
Query query=null; 
query=session.createQuery(hsql);; 

total_count=(query.list(););.size();; //增加---取得总计录数
crossPageInfo= crossPageBean.getCrossPageInfo total_count,pageNo,page_size);; //移动来的
pageNog=pageNo; //移动来的

int start=(pageNog-1);*page_size; 
int rowNum=page_size; 
query.setFirstResult(start);; 
query.setMaxResults(rowNum);; 
offices = query.list();; 

return offices; 
} 
0 请登录后投票
   发表时间:2006-02-20  
total_count=(query.list()).size();


这句会把所有的结果都查出来吧?
我现在就在count()查询总数时遇到了from子句非常复杂的情况,头疼....
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics