08-01
29
Hibernate通用分页
作者:Java伴侣 日期:2008-01-29
Jpage分页—struts+hibernate的通用分页程序本文源自昨夜风网站(www.zuoyefeng.com)名声显赫而招摇的数据持久层框架Hibernate,通过query.setFirstResult和query.setMaxResult来实现了对数据的分页,这个分页的实质在SqlServer中是TOP N的方法,Oracle是rownum<n方法。即直接通过SQL语句,来得到当前页所需的数据。
但是,Hibernate分页,并不能得到页脚,所以尚不通用。承接Jpage分页的方便性,写了这版分页,以方便已与群众。
下面,就是在Hibernate下的通用分页,属于Jpage分页的第三项功能。思路是定义一个Dao类,让其它数据库的dao都继承这个Dao类。
Dao类源文件:
3、Struts的Action调用dao:
4、在JSP中显示:这里采用的是DIV布局
总结,在分页查询的时候,如果加入order by ..倒序排序,程序会报错.下面这个方法不是很严谨:
public List jlist(Query query)
{
String[] str = query.getQueryString().split("from");
String countsql ="select count(*) from "+str[1].trim();
return jlist(query,countsql);
}
原因是由于这句hibernate生成的SQL语句:
select count(*) as x0_0_ from News newsvo0_ order by newsvo0_.id desc
这样的SQL语句难免报错:java.sql.SQLException: 列名 'newsvo0_.id' 在 orDER BY 子句中无效,因为该列未包含在聚合函数中,并且没有 GROUP BY 子句。
下面我修改一下这个方法,加上截取字符串功能:
public List jlist(Query query)
{
String[] str = query.getQueryString().split("from");
String longSql=str[1].trim();
String [] s=longSql.split("order");
System.out.println("s[0].trim():::"+s[0].trim());
/**
* 截取字符串,防止select count(*) as x0_0_ from News newsvo0_ order by newsvo0_.id desc报错:
* java.sql.SQLException: 列名 'newsvo0_.id' 在 orDER BY 子句中无效,因为该列未包含在聚合函数中,并且没有 GROUP BY 子句。
*/
String countsql ="select count(*) from "+s[0].trim();
return jlist(query,countsql);
}
这样,基本就OK了!
但是,Hibernate分页,并不能得到页脚,所以尚不通用。承接Jpage分页的方便性,写了这版分页,以方便已与群众。
下面,就是在Hibernate下的通用分页,属于Jpage分页的第三项功能。思路是定义一个Dao类,让其它数据库的dao都继承这个Dao类。
Dao类源文件:
复制内容到剪贴板 程序代码
package com.xdf.dao;
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.http.*;
import org.hibernate.*;
import org.hibernate.criterion.Projections;
import com.xdf.hibernate.HibernateSessionFactory;
public class Dao {
HttpServletRequest request;
HttpServletResponse response;
Session session;
//定义List集合
private List list;
public int intCountic;
public int PageSize;
public int intPageCount;
public int intPage;
public String nowPage;
public String HttpFile;
//取得网址是的参数
String PageParameter;
public Dao(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
/*
*******得到Session**********
*/
public Session getSession() {
session = HibernateSessionFactory.getSession();
return session;
}
//添加数据
public void add(Object obj) {
}
//修改数据
public void mod(Object obj) {
}
//普通查询
public List list() {
return null;
}
public List jlist(Object query, String countsql)
{
Query q=null;
Criteria cri=null;
List li=null;
boolean bool=false;;
//得到记录总数
if(query instanceof Query) {
q=(Query)query;
bool=true;
intCountic = getCountJsql(countsql);
}
else if(query instanceof Criteria) {
cri=(Criteria)query;
li=cri.list();
if(li.size()==0)
intCountic=0;
else
intCountic=li.size();
}
else
{
System.out.println("出错提示:参数不正确");
return null;
}
try
{
//每页记录数
if (PageSize == 0)
PageSize = 20;
//获得url,如 /user/china.jsp
HttpFile = request.getRequestURI();
//获得当前页数
nowPage = request.getParameter("pages");
//取得网址是的参数
PageParameter = this.urlPath(request);
//如果没有pages参数,则让页数为1
if (nowPage == null) {
intPage = 1;
}
else {
intPage = Integer.parseInt(nowPage);
if (intPage < 1) {
intPage = 1;
}
}
//得到分页总数
intPageCount = ((intCountic + PageSize) - 1) / PageSize;
if (intPage > intPageCount) {
intPage = intPageCount;
}
// 得到list集合
if(bool)
list = q.setFirstResult((intPage - 1) * PageSize).setMaxResults(PageSize).list();
else
list =cri.setFirstResult((intPage - 1) * PageSize).setMaxResults(PageSize).list();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
}
//将分页和页脚传到request中
request.setAttribute("list", list);
request.setAttribute("foot", PageFooter());
return list;
}
public List jlist(Query query)
{
String[] str = query.getQueryString().split("from");
String countsql ="select count(*) from "+str[1].trim();
return jlist(query,countsql);
}
public List jlist(Criteria query)
{
return jlist(query,"");
}
//汇总语句,得到记录总数
public int getCountJsql(String countsql) {
Query q = getSession().createQuery(countsql);
List cc = q.list();
Integer a = (Integer) cc.get(0);
return a.intValue();
}
//页脚显示
/**
* 显示分页内容
* @return
*/
public String PageFooter() {
if (list.size() <= 0) {
return "<span style=\"color:#FF3300;font-size:14px;\">对不起,暂无记录!</span>";
}
String style = "<style> \n";
style += ".page {color: #333333; background-color: #F3F3F3; height: 18px;width: 36px;";
style += "border: 1px solid #333333;margin-right: 1px; margin-left: 1px;} \n";
style += " .fytd {font-size: 12px; color: #333333;}\n";
style += ".fy:link {color: #333333;text-decoration: underline;font-size: 12px;} \n";
style += ".fy:visited {color: #333333;text-decoration: underline;font-size: 12px;} \n";
style += ".fy:hover{color: #000000;text-decoration: none;border: 1px solid #999999;";
style += "background-position: center center;font-size: 12px; background-color: #FFFFFF;} \n";
style += ".fy:active {color: #000000;text-decoration: none;border: 1px solid #999999;";
style += "background-position: center center;padding: 1px 1px 0px;font-size: 12px;background-color: #FFFFFF;} \n";
style += "</style> \n";
String str = "";
int prev = intPage - 1;
int next = intPage + 1;
str = str
+ "<table width=100% border=0 cellspacing=0 cellpadding=1 class=fytd>";
str = str + "<tr><td width=45%>共计:<font color=#FF3300>[" + intCountic
+ "]</font>条 <font color=#FF3300> [" + intPageCount
+ "]</font>页";
str = str + " 第<font color=#FF3300>[" + getIntPage()
+ "]</font>页</td><td width=55%>";
str = str
+ "<table width=275 border=0 align=right cellpadding=0 cellspacing=0 class=fytd>";
//*******
String pstr = HttpFile + "?" + PageParameter.replace("&pages=", "");
pstr = pstr.replace("?pages=", "");
str = str + "<form action=" + pstr
+ " name=formin method=post><tr><td width=195>";
if (intPage > 1) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter + "1"
+ " class=fy>[首页]</A> ";
} else {
str = str + " [首页] ";
}
if (intPage > 1) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter + prev
+ " class=fy>[上一页]</A> ";
} else {
str = str + " [上一页] ";
}
if (intPage < intPageCount) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter + next
+ " class=fy>[下一页]</A> ";
} else {
str = str + " [下一页] ";
}
if (intPageCount > 1 && intPage != intPageCount) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter
+ intPageCount + " class=fy>[尾页]</A>";
} else {
str = str + " [尾页]";
}
str = str
+ "</td><td width=80 align=right><input name=pages type=text class=page value="
+ intPage
+ " size=3 maxlength=5 onkeyup=javascript:value=value.replace(/[^\\d]/g,'')>";
str = str
+ "<input name=Submit2 type=submit class=page value=转到></td></tr></form></table>";
str+="</td></tr></table>";
return style + str;
}
/**
* 对有参数的网址进行改造。。
* 如 index.jsp?id=23&class=23
*/
public String urlPath(HttpServletRequest request) {
String path = "";
String pagepath = "pages=";
String url = request.getQueryString();
//如果无参数
if (url == null || url.equals("")) {
return pagepath;
}
List lista = new ArrayList();
StringTokenizer ss = new StringTokenizer(url, "&");
while (ss.hasMoreTokens()) {
String s = ss.nextToken();
if (s.indexOf("pages") == -1)
lista.add(s);
}
for (int i = 0; i < lista.size(); i++) {
String param = "";
try {
param = new String(lista.get(i).toString().getBytes(
"iso-8859-1"), "gb2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
path += param + "&";
}
return path + pagepath;
}
public int getIntCountic() {
return intCountic;
}
public void setIntCountic(int intCountic) {
this.intCountic = intCountic;
}
public int getIntPage() {
return intPage;
}
public void setIntPage(int intPage) {
this.intPage = intPage;
}
public int getIntPageCount() {
return intPageCount;
}
public void setIntPageCount(int intPageCount) {
this.intPageCount = intPageCount;
}
public String getNowPage() {
return nowPage;
}
public void setNowPage(String nowPage) {
this.nowPage = nowPage;
}
public int getPageSize() {
return PageSize;
}
public void setPageSize(int pageSize) {
PageSize = pageSize;
}
}
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.http.*;
import org.hibernate.*;
import org.hibernate.criterion.Projections;
import com.xdf.hibernate.HibernateSessionFactory;
public class Dao {
HttpServletRequest request;
HttpServletResponse response;
Session session;
//定义List集合
private List list;
public int intCountic;
public int PageSize;
public int intPageCount;
public int intPage;
public String nowPage;
public String HttpFile;
//取得网址是的参数
String PageParameter;
public Dao(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
/*
*******得到Session**********
*/
public Session getSession() {
session = HibernateSessionFactory.getSession();
return session;
}
//添加数据
public void add(Object obj) {
}
//修改数据
public void mod(Object obj) {
}
//普通查询
public List list() {
return null;
}
public List jlist(Object query, String countsql)
{
Query q=null;
Criteria cri=null;
List li=null;
boolean bool=false;;
//得到记录总数
if(query instanceof Query) {
q=(Query)query;
bool=true;
intCountic = getCountJsql(countsql);
}
else if(query instanceof Criteria) {
cri=(Criteria)query;
li=cri.list();
if(li.size()==0)
intCountic=0;
else
intCountic=li.size();
}
else
{
System.out.println("出错提示:参数不正确");
return null;
}
try
{
//每页记录数
if (PageSize == 0)
PageSize = 20;
//获得url,如 /user/china.jsp
HttpFile = request.getRequestURI();
//获得当前页数
nowPage = request.getParameter("pages");
//取得网址是的参数
PageParameter = this.urlPath(request);
//如果没有pages参数,则让页数为1
if (nowPage == null) {
intPage = 1;
}
else {
intPage = Integer.parseInt(nowPage);
if (intPage < 1) {
intPage = 1;
}
}
//得到分页总数
intPageCount = ((intCountic + PageSize) - 1) / PageSize;
if (intPage > intPageCount) {
intPage = intPageCount;
}
// 得到list集合
if(bool)
list = q.setFirstResult((intPage - 1) * PageSize).setMaxResults(PageSize).list();
else
list =cri.setFirstResult((intPage - 1) * PageSize).setMaxResults(PageSize).list();
}
catch(Exception ex)
{
ex.printStackTrace();
}
finally
{
}
//将分页和页脚传到request中
request.setAttribute("list", list);
request.setAttribute("foot", PageFooter());
return list;
}
public List jlist(Query query)
{
String[] str = query.getQueryString().split("from");
String countsql ="select count(*) from "+str[1].trim();
return jlist(query,countsql);
}
public List jlist(Criteria query)
{
return jlist(query,"");
}
//汇总语句,得到记录总数
public int getCountJsql(String countsql) {
Query q = getSession().createQuery(countsql);
List cc = q.list();
Integer a = (Integer) cc.get(0);
return a.intValue();
}
//页脚显示
/**
* 显示分页内容
* @return
*/
public String PageFooter() {
if (list.size() <= 0) {
return "<span style=\"color:#FF3300;font-size:14px;\">对不起,暂无记录!</span>";
}
String style = "<style> \n";
style += ".page {color: #333333; background-color: #F3F3F3; height: 18px;width: 36px;";
style += "border: 1px solid #333333;margin-right: 1px; margin-left: 1px;} \n";
style += " .fytd {font-size: 12px; color: #333333;}\n";
style += ".fy:link {color: #333333;text-decoration: underline;font-size: 12px;} \n";
style += ".fy:visited {color: #333333;text-decoration: underline;font-size: 12px;} \n";
style += ".fy:hover{color: #000000;text-decoration: none;border: 1px solid #999999;";
style += "background-position: center center;font-size: 12px; background-color: #FFFFFF;} \n";
style += ".fy:active {color: #000000;text-decoration: none;border: 1px solid #999999;";
style += "background-position: center center;padding: 1px 1px 0px;font-size: 12px;background-color: #FFFFFF;} \n";
style += "</style> \n";
String str = "";
int prev = intPage - 1;
int next = intPage + 1;
str = str
+ "<table width=100% border=0 cellspacing=0 cellpadding=1 class=fytd>";
str = str + "<tr><td width=45%>共计:<font color=#FF3300>[" + intCountic
+ "]</font>条 <font color=#FF3300> [" + intPageCount
+ "]</font>页";
str = str + " 第<font color=#FF3300>[" + getIntPage()
+ "]</font>页</td><td width=55%>";
str = str
+ "<table width=275 border=0 align=right cellpadding=0 cellspacing=0 class=fytd>";
//*******
String pstr = HttpFile + "?" + PageParameter.replace("&pages=", "");
pstr = pstr.replace("?pages=", "");
str = str + "<form action=" + pstr
+ " name=formin method=post><tr><td width=195>";
if (intPage > 1) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter + "1"
+ " class=fy>[首页]</A> ";
} else {
str = str + " [首页] ";
}
if (intPage > 1) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter + prev
+ " class=fy>[上一页]</A> ";
} else {
str = str + " [上一页] ";
}
if (intPage < intPageCount) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter + next
+ " class=fy>[下一页]</A> ";
} else {
str = str + " [下一页] ";
}
if (intPageCount > 1 && intPage != intPageCount) {
str = str + " <A href=../../" + HttpFile + "?" + PageParameter
+ intPageCount + " class=fy>[尾页]</A>";
} else {
str = str + " [尾页]";
}
str = str
+ "</td><td width=80 align=right><input name=pages type=text class=page value="
+ intPage
+ " size=3 maxlength=5 onkeyup=javascript:value=value.replace(/[^\\d]/g,'')>";
str = str
+ "<input name=Submit2 type=submit class=page value=转到></td></tr></form></table>";
str+="</td></tr></table>";
return style + str;
}
/**
* 对有参数的网址进行改造。。
* 如 index.jsp?id=23&class=23
*/
public String urlPath(HttpServletRequest request) {
String path = "";
String pagepath = "pages=";
String url = request.getQueryString();
//如果无参数
if (url == null || url.equals("")) {
return pagepath;
}
List lista = new ArrayList();
StringTokenizer ss = new StringTokenizer(url, "&");
while (ss.hasMoreTokens()) {
String s = ss.nextToken();
if (s.indexOf("pages") == -1)
lista.add(s);
}
for (int i = 0; i < lista.size(); i++) {
String param = "";
try {
param = new String(lista.get(i).toString().getBytes(
"iso-8859-1"), "gb2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
path += param + "&";
}
return path + pagepath;
}
public int getIntCountic() {
return intCountic;
}
public void setIntCountic(int intCountic) {
this.intCountic = intCountic;
}
public int getIntPage() {
return intPage;
}
public void setIntPage(int intPage) {
this.intPage = intPage;
}
public int getIntPageCount() {
return intPageCount;
}
public void setIntPageCount(int intPageCount) {
this.intPageCount = intPageCount;
}
public String getNowPage() {
return nowPage;
}
public void setNowPage(String nowPage) {
this.nowPage = nowPage;
}
public int getPageSize() {
return PageSize;
}
public void setPageSize(int pageSize) {
PageSize = pageSize;
}
}
复制内容到剪贴板 程序代码
/**
* 注意事项:
* 1、可传递Query或Critera参数
* 2、传递Query对象时,不能使用包括?号的HQL语句。
* 3、使用Critera时,是将所有数据读到List中,从而获得记录数,经测试5万条记录内,差别不明显
*
*/
产品dao类(具体dao):
package com.xdf.dao;
import java.util.List;
import javax.servlet.http.*;
import org.hibernate.*;
import org.hibernate.Transaction;
import com.xdf.bean.PInfo;
import com.xdf.hibernate.HibernateSessionFactory;
import com.xdf.struts.form.*;
import javax.servlet.http.*;
public class PinfoDao extends Dao {
public PinfoDao(HttpServletRequest request,HttpServletResponse response)
{
super(request,response);
}
//添加产品
public void add(Object po) { }
//修改产品
public void mod(Object po) { }
//分页查询
public List list() {
Query query =getSession().createQuery("from PInfo");
//想使用分页,将Query作为参数,传给jlist方法就可以了,这时就可以得到列表和页脚。
//HQL查询、条件查询都返回Query对象,所以都可以。
List li=jlist(query);
//或者 List li=jlist(query,PInfo);
return li;
}
//汇总查询
public List count()
{
return null;
}
}
* 注意事项:
* 1、可传递Query或Critera参数
* 2、传递Query对象时,不能使用包括?号的HQL语句。
* 3、使用Critera时,是将所有数据读到List中,从而获得记录数,经测试5万条记录内,差别不明显
*
*/
产品dao类(具体dao):
package com.xdf.dao;
import java.util.List;
import javax.servlet.http.*;
import org.hibernate.*;
import org.hibernate.Transaction;
import com.xdf.bean.PInfo;
import com.xdf.hibernate.HibernateSessionFactory;
import com.xdf.struts.form.*;
import javax.servlet.http.*;
public class PinfoDao extends Dao {
public PinfoDao(HttpServletRequest request,HttpServletResponse response)
{
super(request,response);
}
//添加产品
public void add(Object po) { }
//修改产品
public void mod(Object po) { }
//分页查询
public List list() {
Query query =getSession().createQuery("from PInfo");
//想使用分页,将Query作为参数,传给jlist方法就可以了,这时就可以得到列表和页脚。
//HQL查询、条件查询都返回Query对象,所以都可以。
List li=jlist(query);
//或者 List li=jlist(query,PInfo);
return li;
}
//汇总查询
public List count()
{
return null;
}
}
3、Struts的Action调用dao:
复制内容到剪贴板 程序代码
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
System.out.println("aabbcc");
PinfoDao dao = new PinfoDao(request,response);
dao.list();
return mapping.findForward("list");
}
HttpServletRequest request, HttpServletResponse response) {
System.out.println("aabbcc");
PinfoDao dao = new PinfoDao(request,response);
dao.list();
return mapping.findForward("list");
}
4、在JSP中显示:这里采用的是DIV布局
复制内容到剪贴板 程序代码
<ul>
<li>产品名称</li>
<li>产品类别</li>
<li>产品价格</li>
<li>操 作</li>
</ul>
<logic:iterate id="da" name="list">
<ul>
<li><bean:write name="da" property="PName" /></li>
<li><bean:write name="da" property="PType" /></li>
<li><bean:write name="da" property="PPrice" /></li>
<li><a href="prod.do id=<bean:write name="da" property="PId" />">删除</a></li>
</ul>
</logic:iterate>
<ul>
<li>
<bean:write name="foot" filter="false"></bean:write>
</li>
</ul>
<li>产品名称</li>
<li>产品类别</li>
<li>产品价格</li>
<li>操 作</li>
</ul>
<logic:iterate id="da" name="list">
<ul>
<li><bean:write name="da" property="PName" /></li>
<li><bean:write name="da" property="PType" /></li>
<li><bean:write name="da" property="PPrice" /></li>
<li><a href="prod.do id=<bean:write name="da" property="PId" />">删除</a></li>
</ul>
</logic:iterate>
<ul>
<li>
<bean:write name="foot" filter="false"></bean:write>
</li>
</ul>
总结,在分页查询的时候,如果加入order by ..倒序排序,程序会报错.下面这个方法不是很严谨:
public List jlist(Query query)
{
String[] str = query.getQueryString().split("from");
String countsql ="select count(*) from "+str[1].trim();
return jlist(query,countsql);
}
原因是由于这句hibernate生成的SQL语句:
select count(*) as x0_0_ from News newsvo0_ order by newsvo0_.id desc
这样的SQL语句难免报错:java.sql.SQLException: 列名 'newsvo0_.id' 在 orDER BY 子句中无效,因为该列未包含在聚合函数中,并且没有 GROUP BY 子句。
下面我修改一下这个方法,加上截取字符串功能:
public List jlist(Query query)
{
String[] str = query.getQueryString().split("from");
String longSql=str[1].trim();
String [] s=longSql.split("order");
System.out.println("s[0].trim():::"+s[0].trim());
/**
* 截取字符串,防止select count(*) as x0_0_ from News newsvo0_ order by newsvo0_.id desc报错:
* java.sql.SQLException: 列名 'newsvo0_.id' 在 orDER BY 子句中无效,因为该列未包含在聚合函数中,并且没有 GROUP BY 子句。
*/
String countsql ="select count(*) from "+s[0].trim();
return jlist(query,countsql);
}
这样,基本就OK了!
评论: 0 | 引用: 0 | 查看次数: 1112
发表评论