SSH实现分页查询
一·实现分页查询的步骤
1.搭好ssh框架
2.实现Hibernate数据持久化层
3.实现业务逻辑层也就是Biz层
4.编写一个封装分页属性类
5.编写action里的代码
6画好页面
7.运行ok
二。下面是具体实现步骤代码
1.编写dao层接口
package com.qinzhongliao.dao;
import java.util.List;
public interface StudentDao {
public List getAllStudents(int pageSize, int startRow)throws Exception;
public int getRows()throws Exception;
}
2.编写dao层接口实现类
package com.qinzhongliao.dao.Impl;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.qinzhongliao.dao.StudentDao;
public class StudentDaoImpl extends HibernateDaoSupport implements StudentDao {
//pageSize是设置数据库每次返回多少条数据 startRow是设置每页从第几条数据开始
public List getAllStudents(int pageSize, int startRow) throws Exception {
Session session=this.getSession();
String hql="from Student";
Query query=session.createQuery(hql);
query.setFirstResult(startRow);
query.setMaxResults(pageSize);
return query.list();
}
//获取返回数据个数
public int getRows()throws Exception{
Session session =this.getSession();
String hql="select count(*) from Student";
Query q=session.createQuery(hql);
//有时候uniqueResult()方法返回的是一个Long类型的变量而不是Integer类型的变量 原因是J2EE版本不一样 所以这里有必要进行一下类型转换
Long lo=(Long)q.uniqueResult();
Integer count=new Integer(String.valueOf(lo));
return count;
}
}
3.编写业务接口Biz
package com.qinzhongliao.Biz;
import java.util.List;
public interface StudentBiz {
public List getAllStudents(int pageSize, int startRow);
public int getRows();
}
4.编写业务接口实现类
package com.qinzhongliao.Biz.Impl;
import java.util.List;
import com.qinzhongliao.Biz.StudentBiz;
import com.qinzhongliao.dao.StudentDao;
public class StudentBizImpl implements StudentBiz {
private StudentDao sdao;
public void setSdao(StudentDao sdao) {
this.sdao = sdao;
}
public List getAllStudents(int pageSize, int startRow) {
try {
return this.sdao.getAllStudents(pageSize, startRow);
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
return null;
}
public int getRows() {
try {
return this.sdao.getRows();
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
return 0;
}
}
5.写一个Pager类用于实现分页属性的封装
package com.qinzhongliao.Page;
public class Pager {
private int totalRows; // 总行数
private int pageSize = 3; // 每页显示的行数
private int currentPage; // 当前页号
private int totalPages; // 总页数
private int startRow; // 当前页在数据库中的起始行
public Pager() {
}
public Pager(int _totalRows) {
totalRows = _totalRows;
totalPages = totalRows / pageSize;
int mod = totalRows % pageSize;
if (mod > 0) {
totalPages++;
}
this.currentPage=1;
startRow = 0;
}
public int getStartRow() {
return startRow;
}
public int getTotalPages() {
return totalPages;
}
public int getCurrentPage() {
return currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalRows() {
return totalRows;
}
public void first() {//首页
currentPage = 1;
startRow = 0;
}
public void previous() {//上一页
if (currentPage == 1) {//如果已经是第一页,就没有上一页,直接返回
return;
}
currentPage--;
startRow = (currentPage - 1) * pageSize;// 算出每一页的开始行
}
public void next() {//下一页
if (currentPage < totalPages) {
currentPage++;
}
startRow = (currentPage - 1) * pageSize;
}
//最后一页
public void last() {
currentPage = totalPages;
startRow = (currentPage - 1) * pageSize;
}
public void refresh(int _currentPage) {
currentPage = _currentPage;
if (currentPage > totalPages) {
last();
}
}
}
6.再写一个PagerHelper类来帮助page类判断是首页还是尾页 或者第几页
package com.qinzhongliao.Page;
import javax.servlet.http.*;
public class PagerHelper {
public static Pager getPager(HttpServletRequest request,
int totalRows) {
// 定义pager对象,用于传到页面
Pager pager = new Pager(totalRows);
// 从Request对象中获取当前页号
String currentPage = request.getParameter("currentPage");
// 如果当前页号为空,表示为首次查询该页
// 如果不为空,则刷新pager对象,输入当前页号等信息
if (currentPage != null) {
pager.refresh(Integer.parseInt(currentPage));
}
// 获取当前执行的方法,首页,前一页,后一页,尾页。
String pagerMethod = request.getParameter("pageMethod");
if (pagerMethod != null) {
if (pagerMethod.equals("first")) {
pager.first();
} else if (pagerMethod.equals("previous")) {
pager.previous();
} else if (pagerMethod.equals("next")) {
pager.next();
} else if (pagerMethod.equals("last")) {
pager.last();
}
}
return pager;
}
}
7.编写action代码
package com.web.struts.action;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.qinzhongliao.Biz.StudentBiz;
import com.qinzhongliao.Page.Pager;
import com.qinzhongliao.Page.PagerHelper;
public class StudentsAction extends DispatchAction {
private StudentBiz sbiz;
public void setSbiz(StudentBiz sbiz) {
this.sbiz = sbiz;
}
public ActionForward getStudents(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
int totalRows = 0;//记录总行数
totalRows=sbiz.getRows();
Pager pager=PagerHelper.getPager(request,totalRows);
List list=sbiz.getAllStudents(pager.getPageSize(),pager.getStartRow());
System.out.print(list.isEmpty());
System.out.print(totalRows);
request.setAttribute("item", list);
request.setAttribute("pager", pager);
request.setAttribute("totalRows", totalRows);
return mapping.findForward("getStudents");
}
}
8.最后就是画页面了
<body>
<html:form action="students.do" method="post">
<html:hidden property="state" value="getStudents" />
<table border="1" align="center" style="width: 500px">
<tr>
<td>
姓名
</td>
<td>
年龄
</td>
</tr>
<logic:notEmpty name="item" scope="request">
<logic:iterate id="list" name="item">
<tr>
<td>
${list.sname}
</td>
<td>
${list.sage}
</td>
</tr>
</logic:iterate>
</table>
</logic:notEmpty>
<table border="1" align="center" style="width: 500px">
<tr>
<td colspan="8" align="right" property="currentPage" />
页 共
<bean:write name="pager" property="totalPages" />
页
<html:link action="students.do?state=getStudents&pageMethod=first"
paramName="pager" paramProperty="currentPage"
paramId="currentPage">首页</html:link>
<html:link
action="students.do?state=getStudents&pageMethod=previous"
paramName="pager" paramProperty="currentPage"
paramId="currentPage">上一页</html:link>
<html:link action="students.do?state=getStudents&pageMethod=next"
paramName="pager" paramProperty="currentPage"
paramId="currentPage">下一页</html:link>
<html:link action="students.do?state=getStudents&pageMethod=last"
paramName="pager" paramProperty="currentPage"
paramId="currentPage">尾页</html:link>
</td>
<td>
共有<%=request.getAttribute("totalRows")%>条记录
</td>
</tr>
</table>
</html:form>
</body>
9.嘿嘿...下面是抄袭别人总结的经验
一般分页应该要具有的功能有
1. 灵活的设置分页大小。可以动态的设置分页大小,而不是写死到代码中。
2. 自动计算总页数。根据分页大小和总记录数自动计算总页数。
3. 获得当前页的页号。
4. 获得当前页的总记录数。一般是最后一页的时候可能会小于分页大小。
5. 判断当前页是否为第一页。
6. 判断当前页是否为最后一页。
7. 判断当前页是否有上一页。
8. 判断当前页是否有下一页。
9. 获得当前页的数据列表。
10. 获得当前页的第一条记录的索引号
11. 获得当前页的最后一条记录的索引号。
二、常用的分页技术
目前常用的分页技术有两种:
1. 第一次访问是读取所有记录,放入session中,然后每次从session对象中读取当前页的数据
2. 每次都访问数据库,从数据库中读取当前页的记录。
这两种方法都各有优缺点,当数据量比较少时,第一种方法无疑是要快一些,因为减少与数据库的连接访问。而当数据量比较大时,比如查询结果可能会是上万条,那么内存的开销是十分大的,放到session中还有一个问题是能不能及时的清除无用的对象。而且这么大数据量在网络中传输也会使系统变得很慢。
第二种方法就是专门解决这个问题的,它每次访问数据库,只读取当前页所需的记录,大大的减少网络传输量;它不会把页数据放到session中,大大提高服务器的性能。
所以第二种方式要优于第一种方法。Session不要乱用,要用也仅仅是存放一些公共变量,相对于占用空间比较少的对象。不适合存放大量的数据,否则在很多个用户同时访问时那么系统会很慢,因为服务器内存被销耗的很厉害