简简单单的分页方案:javascript+Struts+Hibernate

本文介绍了一种在JSP环境中实现动态分页的方法,重点讨论了如何在DAO层使用Hibernate进行分页查询,并展示了如何通过Struts Action和自定义Page对象来管理分页状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

明天就要离开呆了半年学习的地方:杭州,昨天下午在家没心思看书,看了看以前作的demo,想起来作个分页,最初的设想是作一个可复用的,易扩展的.想了很久以本人目前的技术没法完成,但我又急于想作一下,先去西城广场的新华书店看了一下书:Pojo in Action,最后部分谈到动态分页.觉得实施起来还是太复杂.

走出来好像有点思路了!说实话这是我第一次思考从数据库到页面整个流程的分页方案.以前写ASP时,网上有的是封装好的通用分页函数,这次到JSP着实...,

分页技术,好处就不谈了,关键是只能在Dao层处理数据,如果移到Service层,哪就没有必要分页,个人总结一下:

1:逻辑分页

1.1)JDBC有两种方案:

a:用一个动态临时变量

b:用rs.absolute

rs.absolute((number-1) *Page_Size +1 );

1.2)Hibernate

类似JDBC的第二方案(rs.absolute)

  results.setFirstResult((currentCursor-1)*pageSize);
  results.setMaxResults(pageSize);

由于原来的demo用的是struts和hibernate,我的最终思路是这样的,

由于从数据库出来的数据是关健,所以第一步从数据开始,上面你已经看到了,在Hibernate中的Query中有两个方法:

public  Query setFirstResult( int  firstResult)
Set the first row to retrieve. If not set, rows will be retrieved beginnning from row 
0 .
Parameters:
firstResult 
-  a row number, numbered from  0
public  Query setMaxResults( int  maxResults)
Set the maximum number of rows to retrieve. If not set, there is no limit to the number of rows retrieved.
Parameters:
maxResults 
-  the maximum number of rows

在我原来的Dao实现类中加入以下方法:

 

public  Collection < Book >  queryAllRecords( int  currentCursor, int  pageSize)  {
        Collection
<Book> books=new Vector<Book>();
        s
=HibernateUtil.getCurrentSession();
        t
=s.beginTransaction();
        Query results
=s.createQuery("from Book");
        results.setFirstResult((currentCursor
-1)*pageSize);
        results.setMaxResults(pageSize);
        
        Iterator it
=results.list().iterator();
        t.commit();
        HibernateUtil.closeCurrentSession();
        Book b
=null;
        
while(it.hasNext()){
            b
=(Book)it.next();
            books.add(b);
            System.out.println(
"----query item: "+b.getName());
        }

        
return books;
    }
接下来的工作就是在Service层接口中添加相应的调用:
public   interface  BizWorker < T >   {
    Collection
<T> listAllRecord();
    
void addRecord(T t);
    Collection
<T> queryAllRecords(int currentCursor,int pageSize);
}

第二步:修改Struts的Action.

一般跳转到分页显示的页面上的连接,可能是这样的

http://localhost:8080/module/list.do

对应的Action原来的代码是:

 

public   class  BookAction  extends  Action  {
    BizWorker
<Book> bw=new BookService();
    
    @Override
    
public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            
throws Exception {
        
// TODO Auto-generated method stub
        request.setAttribute("product", bw.listAllRecord());
        
return mapping.findForward("access");
    }

}

让它小变一下:

public   class  BookAction  extends  Action  {
    BizWorker
<Book> bw=new BookService();
                      CurrentPage pageEntity
=null;
    @Override
    
public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            
throws Exception {
        
//从session中取回page对象实例
        pageEntity=(CurrentPage)request.getSession().getAttribute("page");
        
if(pageEntity==null){
            
//1.说明这是第一次发过来的请求
            
//用查到的总记录数+页面显示的记录数(5)=创建一个page对象实例
            pageEntity=new CurrentPage(new BookService().getTotalNumber(),5);
            
//保存到session中
            request.getSession().setAttribute("page", pageEntity);
        }

        request.setAttribute(
"product", bw.queryAllRecords(pageEntity.getCurrentPage(), 5));
        
return mapping.findForward("access");
    }

}

本来想重用该Action,但出于我用JavaScript动态改变连接:

从:

http://localhost:8080/module/list.do

变成

http://localhost:8080/module/list.do?page=param

如果在没有点击分页面板的情况下刷新,会抛出类型转换异常.所以此处又加了一个Action:

 

public   class  ShowPage  extends  Action  {
                    CurrentPage pageEntity
=null;
                    BizWorker
<Book> bw=null;
    @Override
    
public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            
throws Exception {
        
// TODO Auto-generated method stub
        
//2:非第-次请求,url中多了page参数
        
//用传递过来的参数更新session中page的成员:currentpage,的值
        pageEntity=(CurrentPage)request.getSession().getAttribute("page");
        Integer page
=Integer.parseInt(request.getParameter("page"));
        
if(page==null){
            page
=page.valueOf(1);
        }

        pageEntity.setCurrentPage(page);
        bw
=new BookService();
        request.setAttribute(
"product", bw.queryAllRecords(pageEntity.getCurrentPage(), 5));
        
return mapping.findForward("access");
    }

}

原来这两个Action我写在一起,发现异常时,没想到解决方案 ,所以分开了!如果你有好的解决办法可以通知我一下,不盛荣兴.

第三步:一个Pojo实体

用来存储和计算:总页数,当前页数,数据库中的记录数.

构造这个对象要用的两个参数是:

3.1.数据库的总记录数,

必须在第一次请求完成时拿到,也就是这个:

http://localhost:8080/module/list.do

动作执行之前拿到:new BookService().getTotalNumber()

2.每页显示的记录数.

我硬编码了:5

pageEntity=new CurrentPage(new BookService().getTotalNumber(),5);

这行执行后就构造了一个page的实体,并将其保存到session中,我的page Pojo实体源码:

 

public   class  CurrentPage  implements  java.io.Serializable {
    
//总数量total
    private int total;
    
//当前数的页数
    private int currentPage=1;
    
//单页的记录数量
    private int pageRecords;
    
//总页数
    private int totalPages;    
    
public CurrentPage() {}
    
public CurrentPage(int total, int pageRecords) {
        
super();
        
this.total = total;
        
//this.strLink = strLink;
        this.pageRecords = pageRecords;
    }


    
public int getTotal() {
        
return total;
    }

    
public void setTotal(int total) {
        
this.total = total;
    }


    
public int getPageRecords() {
        
return pageRecords;
    }

    
public void setPageRecords(int pageRecords) {
        
this.pageRecords = pageRecords;
    }

    
    
public int getCurrentPage() {
        
return currentPage;
    }

    
public void setCurrentPage(int currentPage) {
        
if(currentPage<=1){
            
this.currentPage=1;
        }
else if(currentPage>=this.getTotalPages()){
            
this.currentPage=this.getTotalPages();
        }
else{
            
this.currentPage = currentPage;
        }

    }


    
public int getTotalPages() {
        
int temp=0;
        
if(this.getTotal()%this.getPageRecords()==0){
            temp
=this.getTotal()/this.getPageRecords();
        }
else{
            temp
=this.getTotal()/this.getPageRecords()+1;
        }

        
return temp;
    }

}

最后就只有页面部分了:

1:JavaScript部分.关健的部分

 

< script  type ="text/JavaScript" >
//<![CDATA[
var globalLink;
function getRequestLink(){
    globalLink
=window.location.href;
    
if(globalLink.lastIndexOf("page=")==-1){
        globalLink
=globalLink.replace("list","showpage")+"?";
    }

}

function getRequestPageNumber(param){
    localLink
="";
    
if(globalLink.lastIndexOf("page=")==-1){
        localLink
=globalLink+"page="+param;
    }
else{
        localLink
=globalLink.replace(/=d/g,"="+param);
    }

    
return localLink;
}

//]]>
</ script >

 说明:

getRequestLink函数的作用是在页面加载完成之后来获得当前的URL地址

<body onload="getRequestLink()">

该URL地址经过替换,把原来的list.do换成showpage.do?

getRequestPageNumber函数的作用是再处理一下替换后的URL,并加上参数page

http://localhost:8080/module/showpage.do?page=param

以下是分页面板的代码:

< div id = " pagepanel " >
    
< dl >
        
< dt > Results Page: </ dt >
        
< dd >
            
< a href = " javascript:window.location.replace(getRequestPageNumber(<%=((CurrentPage)request.getSession().getAttribute( " page " )).getCurrentPage()-1 %>)); " > Prev </ a >
        
</ dd >
        
<%
        CurrentPage p
= (CurrentPage)request.getSession().getAttribute( " page " );
        
for ( int  i = 1 ;i <= p.getTotalPages();i ++ ) {%>
        
<dd>
            
<a href="javascript:window.location.replace(getRequestPageNumber(<%=i %>));"><%=%></a>
        
</dd>
        
<%}
  %>
        
< dd >
            
< a href = " javascript:window.location.replace(getRequestPageNumber(<%=((CurrentPage)request.getSession().getAttribute( " page " )).getCurrentPage()+1 %>)); " > Next </ a >
        
</ dd >
        
< dd ><%= p.getCurrentPage()  %>/<%= p.getTotalPages()  %></ dd >
    
</ dl >
</ div >
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值