龍行天下

            政 博
          隨筆 - 23, 文章 - 0, 評論 - 12, 引用 - 0
          數據加載中……

          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

          主站蜘蛛池模板: 孙吴县| 东乡县| 永和县| 海丰县| 哈密市| 丹巴县| 伊川县| 高尔夫| 道孚县| 高碑店市| 梁平县| 新竹市| 正阳县| 建昌县| 莱西市| 柞水县| 鄂托克旗| 穆棱市| 永新县| 淮安市| 百色市| 江口县| 宁陵县| 调兵山市| 沛县| 延长县| 巩义市| 鄂伦春自治旗| 卫辉市| 穆棱市| 邵阳市| 汽车| 年辖:市辖区| 镇康县| 稷山县| 徐闻县| 苗栗市| 临汾市| 泰宁县| 广西| 沁水县|