一、ssh2 简单分页:
前台显示数据难免会涉及到分页,而这个例子适合新手学习如何进行分页的实现。
dao层接口方法
//pageSize是设置数据库每次返回多少条数据 pageNow是设置每页从第几条数据开始
public List<?> excuteQueryByPage(String hql,int pageNow,int PageSize);
/*获取行数*/
public int getAllRowCount(String hql);
实现dao的方法
//通过spring容器注入
private SessionFactory sessionFactory;
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public List<?> excuteQueryByPage(String hql, int pageNow, int PageSize) {
// TODO Auto-generated method stub
Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
query.setFirstResult(pageNow); //从第pageNow条记录开始
query.setMaxResults(PageSize); //取出PageSize条记录
List<?> list = query.list();
return list;
}
/**
* 返回记录数
*/
@Override
public int getAllRowCount(String hql) {
// TODO Auto-generated method stub
Query queryObject = this.sessionFactory.getCurrentSession().createQuery(hql);
Object obj = queryObject.uniqueResult();
int totalCount=Integer.parseInt(obj.toString());
return totalCount;
}
service层的接口
//分页查询
public List queryForPage(int pageSize,int currentPage);
public int getRows();
service层的接口的实现
pythonDao dao;
public pythonDao getDao() {
return dao;
}
public void setDao(pythonDao dao) {
this.dao = dao;
}
@Transactional
public List queryForPage(int pageSize, int currentPage) {
// TODO Auto-generated method stub
try {
String hql = "from Comment";
return dao.excuteQueryByPage(hql, currentPage, pageSize);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return null;
}
@Transactional
public int getRows() {
// TODO Auto-generated method stub
String hql = "select count(*) from Comment";
return dao.getAllRowCount(hql);
}
action中的代码
private int currentPage = 1;
private PageBean pageBean; // 包含分布信息的bean
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public String showComment()
{
int rows = 0;
rows = pys.getRows();
PageBean page = PageHelper.getPage(currentPage, rows);
page.setStartRow((currentPage-1) * page.getPageSize());
List<Comment> comment = (List<Comment>)pys.queryForPage(page.getPageSize(), page.getStartRow());
request.put("comment", comment); //protected Map<String, Object> request;
request.put("page", page);
return "success";
}
PageBean中封装有分页的信息,总页数,总记录数,页面大小等属性。
public class PageBean {
private int allRow; //总记录数
private int totalPage; //总页数
private int currentPage; //当前页数
private int pageSize = 8; //每页记录数
private int startRow; // 当前页在数据库中的起始行
public int getAllRow() {
return allRow;
}
public void setAllRow(int allRow) {
this.allRow = allRow;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public boolean isFirstPage()
{
return currentPage == 1;
}
public boolean isLastPage()
{
return currentPage == totalPage;
}
public boolean isHasNextPage()
{
return currentPage != totalPage;
}
public boolean isHasPrePage()
{
return currentPage != 1;
}
public int getStartRow() {
return startRow;
}
public void setStartRow(int startRow) {
this.startRow = startRow;
}
public PageBean(int _allRows) {
// TODO Auto-generated constructor stub
this.allRow = _allRows;
totalPage = allRow % pageSize == 0 ? allRow/pageSize : allRow/pageSize + 1;
this.currentPage = 1;
startRow = 0;
}
public void last()
{
currentPage = totalPage;
startRow = (currentPage - 1) * pageSize; //算出每一页的开始行
}
public void refresh(int _currentPage) {
currentPage = _currentPage;
if (currentPage > totalPage) {
last();
}
}
}
同时创建一个PageHelper类来进行判断
public class PageHelper {
public static PageBean getPage(int currentPage,int totalRows)
{
// 定义pager对象,用于传到页面
PageBean page = new PageBean(totalRows);
if (currentPage != 0) {
page.refresh(currentPage);
}
return page;
}
}
struts.xml文件中添加
<action name="comment" class="actions.IndexAction" method="showComment">
<result type="dispatcher">/comment.jsp</result>
</action>
接下来是界面的显示部分
<!-- List start -->
<s:iterator value="#request.comment" var="list">
<div class="cc_item">
<div class="itemuser">
<img alt="太帅无法显示" src="<s:property value="#list.userimg" />">
<p><s:property value="#list.username" /></p>
</div>
<div class="itemcontent">
<p class="time">发表时间:<s:property value="#list.time" /></p>
<p class="pstyle"><s:property value="#list.content" /></p>
<div class="bottom"><span>回复(0)</span></div>
</div>
</div>
</s:iterator>
<!-- List end -->
<div class="pagination" style="text-align: center;">
<ul><% PageBean pagebean = (PageBean)request.getAttribute("page");
int totalPage = pagebean.getTotalPage(); //总页数
int currentPage = pagebean.getCurrentPage(); //当前页
//如果是第一页
if(pagebean.isFirstPage()){
for(int i=0; i<totalPage; i++){
%>
<li><a href="comment.action?currentPage=<%=i+1 %>"><%=i+1 %></a></li>
<%}%>
<li><a href="comment.action?currentPage=<%=currentPage+1%>">»</a></li>
<%}
//如果是最后一页
if(pagebean.isLastPage()){
%>
<li><a href="comment.action?currentPage=<%=currentPage-1%>">«</a></li>
<%
for(int i=0; i<totalPage; i++){
%>
<li><a href="comment.action?currentPage=<%=i+1 %>"><%=i+1 %></a></li>
<% }}
//如果不是
if(!pagebean.isLastPage() && !pagebean.isFirstPage()){
%>
<li><a href="comment.action?currentPage=<%=currentPage-1%>">«</a></li>
<%
for(int i=0; i<totalPage; i++){
%>
<li><a href="comment.action?currentPage=<%=i+1 %>"><%=i+1 %></a></li>
<%}%>
<li><a href="comment.action?currentPage=<%=currentPage+1%>">»</a></li>
<%}%>
</ul>
</div>
分页到这里就结束了,该分页只是简单的分页,功能简单,局限性很大。后续功能有待完善,这只是拿来当课设的一部分用的。
二、常用的分页技术
目前常用的分页技术有两种:
1. 第一次访问是读取所有记录,放入session中,然后每次从session对象中读取当前页的数据
2. 每次都访问数据库,从数据库中读取当前页的记录。
这两种方法都各有优缺点,当数据量比较少时,第一种方法无疑是要快一些,因为减少与数据库的连接访问。而当数据量比较大时,比如查询结果可能会是上万条,那么内存的开销是十分大的,放到session中还有一个问题是能不能及时的清除无用的对象。而且这么大数据量在网络中传输也会使系统变得很慢。
第二种方法就是专门解决这个问题的,它每次访问数据库,只读取当前页所需的记录,大大的减少网络传输量;它不会把页数据放到session中,大大提高服务器的性能。
所以第二种方式要优于第一种方法。Session不要乱用,要用也仅仅是存放一些公共变量,相对于占用空间比较少的对象。不适合存放大量的数据,否则在很多个用户同时访问时那么系统会很慢,因为服务器内存被销耗的很厉害