這兩個星期以來,我把原來用struts開發的一個測試工具改用struts+hibernate來實現,首先從心情上來,整個開發過程中始終保持愉快和平和,“原來開發可以這樣愉快?”,再一點就是開發效率上高效了許多。 ????? 現在sun又加入jdocentral.com開始著手JDO2.0,想想看等它出臺以后將是一個怎樣激動人心得場面,讓我們拭目以待。 ????? ????? 用Hibernate來操縱持久數據非常簡單,在這里一些簡單的查詢我會一筆帶過,本文著重說明在綜合查詢兼有分頁的時候我的一些經驗,如果網友覺得我的方案還有不足的地方,也請和我討論,我的email:plateau_t@sina.com. ????? ????? 第一部分: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); ?????? ?????
|