第一部分:
Hibernate
提供的查询接口或其方法
(此部分不做深究,请参考
hibernate
手册)
1
。根据
ID
查询
要用到
Session
接口的
load
方法。
load(Class theClass, Serializable id)
load(Class theClass, Serializable id, LockMode lockMode)
load(Object object, Serializable id)
2
。
HQL
语句进行查询
2
。
1
利用
Query
接口,
Query
由
Session
里的
createQuery()
来产生一个查询
1)
不带参数的查询(这类比较简单)
Query query=session.createQuery("select user from User as user");
2)
带参数的查询
Query query=session.createQuery("select user from User as user where user.name=?");
query.setString(0,name)//
假设
name
为传过来的参数
Query query=session.createQuery("select user from User as user where user.name=:name");
query.setString("name",name)//
假设
name
为传过来的参数
(
多个参数以此类推
)
利用
Session
接口的
find
查询
find(String query)
find(String query, Object[] values, Type[] types)
find(String query, Object value, Type type)
均返回
list
如
:
List list=session.find("select user from Users as user where user.name=?",name,Hibernate.STRING)
List list=session.find("select user from Users as user where user.name=? and user.pw=?",new Object[]{name,pw},new Type[]{Hibernate.STRING,Hibernate.STRING})
{
推荐使用
Query
的方法进行查询
}
第二部分:
hibernate
综合查询解决方案
(此部分详细实例说明,如有不足的地方请写信给我)
大家从第一部分可以看到,带有参数的查询,必须使用到
Query
接口
,
如上边:
Query query=session.createQuery("select users from Users as users where users.name=?");
query.setString(0,name)//
假设
name
为传过来的参数
但是在系统中如何才能写一个公用的查寻方法呢?咋一看,似乎是不可以的,因为每一次查询的参数不一样,参数的数量不一样(如下代码),那么我们如何提取共性呢?
Query query=session.createQuery("select users from Users as users where users.name=? and users.pw=?");
query.setString(0,name)//
假设
name
为传过来的参数
query.setString(1,pw);
首先说明,我的解决方案是从
Seesion
接口的
find
方法找到出口的,如下为
Session
接口得
find()
方法之一:
find(String query, Object[] values, Type[] types)
其中
Object[]
为存放参数值的数组,
Type[]
为存放参数类型的数组,他们的顺序是和
query
里
“
?
”
的顺序是相同的。那么我为什么不用该
find
方法呢,因为如果有分页的情况,那么该方法将不适用。
下面详细要说明的解决方案:
首先我想创建三个新的对象:
Paras.java
(参数对象)
ParasList.java
(参数集合对象)
HQuery.java
(感谢我的同事
camel
提供注释良好的代码)
1
。
Paras.java
(参数对象)
package com.ifreeway.homegrown.testing.waf;
/**
*
* <p>Title:
定义一个
sql
语句的条件参数类
</p>
* <p>Description:
可以使用有序的参数集合传送给
sql/hql
语句
</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: ifreeway</p>
* @author camel
* @version 1.0
*/
public class Paras {
/**
*
参数名称
*/
private Object pName;
/**
*
参数类型编码,于
java.sql.types
中的类型保持一致
*/
private int typeNo;
public Object getPName() {
return pName;
}
public void setPName(Object pName) {
this.pName = pName;
}
public int getTypeNo() {
return typeNo;
}
public void setTypeNo(int typeNo) {
this.typeNo = typeNo;
}
}
2
。
ParasList.java
(参数集合对象)
package com.ifreeway.homegrown.testing.waf;
import java.util.ArrayList;
/**
*
* <p>Title:
参数集合类
</p>
* <p>Description:
封装
sql/hql
的参数到该集合类,便于处理和传递
</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: ifreeway</p>
* @author camel
* @version 1.0
*/
public class ParaList extends ArrayList {
/**
*
在指定位置添加一个参数对象
* @param index
:参数的索引值
* @param p
:需要加入的参数对象
*/
public void addParas(int index,Paras p){
super.add(index,p);
}
/**
*
在集合的最后位置添加一个参数对象
* @param p
:需要加入的参数对象
*/
public void addParas(Paras p){
super.add(p);
}
/**
*
取得指定位置的参数对象
* @param index
:参数的索引值
* @return
:参数对象
*/
public Paras getParas(int index){
return (Paras)super.get(index) ;
}
/**
*
取得指定参数的索引
* @param p
:参数对象
* @return
:参数索引
*/
public int indexofParas(Paras p){
return super.indexOf(p) ;
}
/**
*
从集合中去掉一个指定的参数对象
* @param index
:参数索引
*/
public void removeParas(int index){
super.remove(index) ;
}
}
3
。
HQuery.java
package com.ifreeway.homegrown.testing.waf;
/**
*
* <p>Title: HQL
的语句封装类
</p>
* <p>Description:
该对象封装
HQL
的查询语句,参数集合,排序参数,分组参数,单页起始地址
</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company:ifreeway </p>
* @author camel
* @version 1.0
*/
public class HQuery {
/**
* HQL
查询语句
*/
private String queryString;
/**
*
参数集合对象
*/
private ParaList paralist;
/**
*
排序字段
*/
private String orderby;
/**
*
分组字段
*/
private String groupby;
/**
*
分页起始查询地址
*/
private int pageStartNo;
/**
*
取得一个
Hibernate
的
Query
对象
* @return
:
Query
对象
*/
public String getQueryString() {
return queryString;
}
/**
*
设置一个
HQL
查询字符串
* @param queryString
:查询字符串
*
*/
public void setQueryString(String queryString) {
this.queryString =queryString;
}
/**
*
取得参数集合对象
* @return
:参数集合对象
*/
public ParaList getParalist() {
return paralist;
}
/**
*
设置参数集合对象
* @param paralist
:参数集合对象
*/
public void setParalist(ParaList paralist) {
this.paralist = paralist;
}
/**
*
取得排序字段
* @return
:排序字段
*/
public String getOrderby() {
return orderby;
}
/**
*
设置排序字段
* @param orderby
*/
public void setOrderby(String orderby) {
this.orderby = orderby;
}
/**
*
取得分组字段
* @return
*/
public String getGroupby() {
return groupby;
}
/**
*
设置分组字段
* @param groupby
*/
public void setGroupby(String groupby) {
this.groupby = groupby;
}
/**
*
取得页起始地址
* @return
*/
public int getPageStartNo() {
return pageStartNo;
}
/**
*
设置页起始地址
* @param pageStartNo
*/
public void setPageStartNo(int pageStartNo) {
this.pageStartNo = pageStartNo;
}
}
上面三个对象的关系是:
用
Paras
来装载每一个查询参数
Paras paras=new Paras();
paras.setPName(...);
paras.setTypeNo(...);
然后放在
ParasList
中
ParasList paraslist=new ParasList();
paraslist.add(paras)
最后把填充以后的
ParasList
集合给
HQuery
HQuery hquery=new HQuery();
hquery.setParalist(paraslist);
先面我们写一个公用查寻方法,来实现我们的综合查询:
/**
*
*
综合查询,首先实例化
HQuery
* @see com.ifreeway.homegrown.testing.common.waf.DBHandler#find(com.ifreeway.homegrown.testing.common.waf.HQuery)
*/
public List find(HQuery _query) throws HibernateException {
List itr = null;
try {
StringBuffer query_str = new StringBuffer(_query.getQueryString());
//
是否要排序
if (_query.getOrderby() != null) {
query_str.append(_query.getOrderby());
}
//
是否要分组
if (_query.getGroupby() != null) {
query_str.append(_query.getGroupby());
}
Session session = getSession();
Query query = session.createQuery(query_str.toString());
if (_query.getParalist() != null) {
List list = _query.getParalist();
for (int i = 0; i < list.size(); i++) {
Paras param = (Paras) list.get(i);
switch (param.getTypeNo()) {//
此处要根据参数类型的增加要增加相应的
“case”
case Types.VARCHAR :
query.setString(i, param.getPName().toString());
break;
case Types.INTEGER :
query.setInteger(
i,
((Integer) param.getPName()).intValue());
break;
case Types.DATE :
query.setDate(i, (java.sql.Date) param.getPName());
break;
case Types.DOUBLE :
query.setDouble(
i,
((Double) param.getPName()).doubleValue());
break;
case Types.BOOLEAN :
query.setBoolean(
i,
((Boolean) param.getPName()).booleanValue());
break;
case Types.CHAR :
query.setCharacter(
i,
((Character) param.getPName()).charValue());
break;
case Types.JAVA_OBJECT :
query.setEntity(i, (BaseModel) param.getPName());
break;
}
}
}
//
是否存在分页,当
_query.getPageStartNo()==0
是不分页
if (_query.getPageStartNo() != 0) {
int pageno = _query.getPageStartNo();
query.setFirstResult((pageno - 1) * Constants.RECORD_PER_PAGE);
query.setMaxResults((pageno) * Constants.RECORD_PER_PAGE);
}
itr = query.list();
closeSession();
} catch (Exception e) {
}
return itr;
}
好了一旦我们做好了上边的工作,查询对我们来说将是很容易的一件事情,而且可以达到公用,是不是省了许多力气?下面我将实例化一个例子来进一步说明:
例子:
HQuery hquery=HQuery();
hquery.setQueryString("select users from Users as users where users.name=? and users.sex=?");
hquery.setOrderby("order by users.age desc");
//
如果要分页,把当前页
curpage
传递给
hquery
hquery.setPageStartNo(curpage);
//
实例化参数,本例为两个参数
Paras paras1=new Paras();
paras1.setPName(name);
paras1.setTypeNo(Types.VARCHAR);
Paras paras2=new Paras();
paras2.setPName(sex);
paras2.setTypeNo(Types.INTEGER);
ParasList paraslist=new ParasList();
paraslist.add(paras1);
paraslist.add(paras2);//
注意顺序
hquery.setParalist(paraslist);
//
好了,做好准备工作,调用查寻方法得到结果
List list=find(hquery);
完成,有兴趣的网又可以据此跳到
find
中看看具体执行情况,如果这样相信你会有更进一步得了解。还是那句话,这个解决方案也有不足的地方,如果你有更好的意见或方法,请和我联系。