Hibernate查詢解決方案
第一部分:
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
中看看具體執行情況,如果這樣相信你會有更進一步得了解。還是那句話,這個解決方案也有不足的地方,如果你有更好的意見或方法,請和我聯系。
posted on 2006-05-03 20:03 feingto 閱讀(429) 評論(0) 編輯 收藏 所屬分類: Java Web