hibernate 数据分页显示 及 分页导航栏的设置

一个小案例 hibernate+struts2 对一个教室信息进行分页显示

只是对一个教室信息(教室名字,教室地址)在页面上进行简单分页,没有多加美工的前端处理,初学者学习javaee如果有不足的地方还请批评指正。

这里是学生管理系统项目的小分支,一些地方是默认作好的
1.这是教室模块的实现,在页面上显示了所提交到数据库表中的教室信息,要进行分页显示
2.这里前端对应着room.jsp,后端对应着RoomAction 和 RoomDAO 
3.room.jsp是后台管理的页面,是通过访问action方法的方式访问 main方法跳转到教室管理页面。
4."roommain"是在struts.xml文件中配置的页面
5.整个action在配置文件中的配置是采用通配符的方式

基本效果:



一、编写一个类Pager来存放分页信息

  类中的属性:当前页  pageNo

     总页数  pageCount

     每页的记录数  pageSize  初始化为4

     分页按钮个数  btnCount   初始化为4

package model;

public class Pager {
	private int pageNo;//当前页
	private int pageSize=4;//每页有都少数据
	private int pageCount;//总页数
	private int btnCount=4;//分页按钮个数
	public int getPageNo() {
		return pageNo;
	}
	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public int getPageCount() {
		return pageCount;
	}
	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}
	public int getBtnCount() {
		return btnCount;
	}
	public void setBtnCount(int btnCount) {
		this.btnCount = btnCount;
	}

}


二、在DAO中写方法
  这里要写两个方法,一个是得到当页的数据的方法,一个是设置总页数的方法。

(1) 在得到当页数据这里注意query的两个方法:
A、query.setFirstResult();  设置当前页上的第一条信息是数据库中的第几条记录。
这里分析:例如每页显示10条消息:
第一页 0-9      起始记录为(1-1)*10=0
第二页 10-19  起始记录为(2-1)*10=10
类推可得当前页  的起始记录为  (pageNo-1)*pageSize(当前是第pageNo页,每页显示pager.pageSize条数据,这里是初始化了每页多少条数据,pageNo是在Action中传来的当前页码)

B、query.setMaxResults();  设置当前页显示最大数据量,与Pager类中pageSize属性对应
执行完这两个方法之后,query.list就是当前页的教室信息

//拿到当前页码所有教室信息的方法
	@SuppressWarnings("unchecked")
	public List<Room> getAllRoomsByPageNo(Pager pager)
	{
		String hql="from Room";
		//这里要创建一个事务,否则后边删除的时候会在页面显示上出现错误
		session=HibernateUtil.openSession();
		session.beginTransaction();
		Query query= session.createQuery(hql);
		
		//设置list为当前页的教室数据
		//(1)设置当前页起始数据是哪条数据
		query.setFirstResult((pager.getPageNo()-1)*pager.getPageSize());
		//(2)设置当前页的最大显示数据数量
		query.setMaxResults(pager.getPageSize());
		
		//这时候获得的list就是当前页的list
		List<Room> list=query.list();
		
		session.getTransaction().commit();
		session.close();
		return list;
	}

(2)设置最大(总)页数的方法中,是通过拿到所有记录数再除以每页显示的数据设置的。这里要加入不能整除的判断
	//分页的时候计算总页数的方法
	@SuppressWarnings("unchecked")
	public void initPageCount(Pager pager)
	{
		String hql="from Room";
		//这里要创建一个事务,否则后边删除的时候会在页面显示上出现错误
		session=HibernateUtil.openSession();
		session.beginTransaction();
		Query query= session.createQuery(hql);
		List<Room> list= query.list();//此时得到的是所有教室的信息
		
		//设置总共有多少页,这里在定义Pager类的时候初始化了一下每页有4条数据
		pager.setPageCount(list.size()/pager.getPageSize());
		if(list.size()%pager.getPageSize()>0)
		{
			//如果总记录数和每页记录数不能整除,总页数加1
			pager.setPageCount(pager.getPageCount()+1);
		}
		session.getTransaction().commit();
		session.close();
	}


三、在Action的main方法中写代码。
因为是访问这个方法跳转到room.jsp页面上,在这个方法中将前端传来的当前页码的这个对象注入到一个Pager实例化的对象中。DAO方法中参数都是这个实例变量,这样只要在Action中定义一个属性pageNo就可以使用类中其他变量的值。

(1)设计是点击页码导航栏中的页码数,传入到后端action中,当我们从主页面点后台管理的方式访问room.jsp时,并不像点击导航栏页码一样,会传入后台当前页cpage属性,这样会使cpage属性为0,这样去获得第0页的第一条数据时,算出的是负数,会出现错误。又因为这样访问页面是通过Action中的main方法访问的,可以在main方法中加入这个属性的判断,如果当前页是0,则设置为第一页,这样以后台管理的方式去访问页面显示的就是第一页的教室数据
if(cpage==0)
{
  cpage=1
}

(2)当拿到本页的数据之后,键值对方式存放在actioncontext中,这里因为访问action是容器内跳转,所以在页面上可以直接拿到这个当前页码下的数据信息(键:"ROOMS"  值:list)。前端页面可以用struts2 标签去拿到数据。这里标签中用的是EL表达式拿出数据,补充一下EL表达式在页面上拿数据所属范围对象的顺序:EL表达式取数据时的查找对象顺序:   page--> request--> session--> application。   

这里存放在ActionContext 中,相当于存放在request中

<s:if test="#ROOMS!=null">
<table class="bordered">
<tr><th>序号</th><th>教室名称</th><th>教室位置</th><th>删除</th><th>修改</th></tr>
<s:iterator value="#ROOMS" id="croom" status="st">
<tr><td>${st.index+1}</td><td>${croom.name}</td><td>${croom.address}</td>
<td><input type="button" value="删除" class="delete" lang="${croom.id}"/></td>
<td><input type="button" value="修改" class="modify" lang="${croom.id}"/></td>
</tr>
</s:iterator>
</table>
(3)在这里可以通过StringBulider的append方法去将导航栏做出来(字符串追加形成一个个超链接)。具体怎么设置详见代码。可以输出到控制台中看看自己写的标签对不对。  如果显示当前页的页码的时候也要有所区分。

这里Pager类中有一个属性分页按钮的个数。如果有很多页的话肯定要规定一下 一页 上显示多少个页码链接。
例如:百度中点到第八页的时候,规定页面上显示页码的个数,能点击的第一个为第三页


所以在设置导航栏的时候,要根据初始化的 页码标签个数 设置一下显示 当前页的数据时,下面页码导航栏的页码 起始和终止的页数,这里还要注意当点击的是第一页和最后一页的时候显示页码的情况。这里暂时来回判断比较麻烦,希望阅读本文的读者可以指出更好的设计页码导航栏的方法。


代码:
//在后台管理点击跳转到room.jsp页面的方法,这里面添加了分页和添加分页导航栏的内容
	public String main()
	{
		//如果是从后台访问room.jsp页面,这里没有点击导航栏中的当前页码按钮,后台action中拿到当前页码为0,此时当做第一页处理
		//这时在DAO方法中去计算第几条开始的时候,如果当前页码为0,计算本页第一条数据是第几条记录的时候,出现负数错误,这里设置为第一页
		if(pageNo==0)
		{
			pageNo=1;
		}
		
		ActionContext ctx= ActionContext.getContext();
		StringBuilder str=new StringBuilder();//为后边打印导航页码用
		
		//拿到request对象,然后拿到根目录
		String path=ServletActionContext.getRequest().getContextPath();
		
		//这里应该得到的是分页之后的当前页教室数据,应该在DAO方法中加入参数pager。
		//这里不加入action中定义的当前页属性,应该是把这个当前页属性设置到pager对象中,再传入pager,好使用这个类中的其他属性
		Pager pager=new Pager();
		//计算总页数
		rdao.initPageCount(pager);
		//将当前页这个属性(从前端传过来) 注入到一个Pager对象当中
		pager.setPageNo(pageNo);
		List<Room> list=rdao.getAllRoomsByPageNo(pager);//这里得到就是当前页的教室数据
		if(list.size()>0)
		{
			
			//存放数据
			ctx.put("ROOMS", list);
			
			//设置页码导航栏
			int btns=pager.getBtnCount();//btns是每页显示的页码按钮数
			btns=btns/2;
			int start=pageNo-btns;//每一页页码按钮的开始
			int end=pageNo+btns;//每一页页码按钮结束
			//对页码进行判断
			if(start<1)
			{
				start=1;
				end=start+btns*2;
			}
			if(end>pager.getPageCount())
			{
				end=pager.getPageCount();
				start=end-btns*2;
			}
			if(start<1)
			{
				start=1;
			}
			//循环准备页码导航栏数据
			for(int i=start;i<=end;i++)
			{
				str.append("<a href='"+ path +"/room/main?pageNo="+i+"'>");
				//如果显示当前页,要区别显示
				if(pageNo==i)
				{
					str.append("<font color='yellow'><b>");
					str.append(i);
					str.append("</b></font>");
				}
				else
				{
					str.append(i);
				}
				str.append("</a>");
				str.append("  ");
			}
			
			str.append("<br>");
			ctx.put("NAVBAR", str.toString());
			
			//打印到输出台,看看是否输入错误
			System.out.println(str.toString());
		}
		return "roommain";
	}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值