Hibernate的createSQLQuery查詢的小例子

 




當我們用HQL進行子查詢的時候,如select * from Tree where pid in (select id from Tree,此時HIBERANTE就會報錯,說什麼*號錯誤之類的。但如果將*改爲Tree類裏的所有子段時就不會有問題了。就會像平時一樣第一行數據返 回一個Object[],然後你再根據Tree類裏字段對Object[]數組裏的值進行轉換。這樣一來比較麻煩。今天發現如果我SQL來查有一個方法可 以返回一個對象的。 
Configuration config = new Configuration().configure(); 
SessionFactory sf     = config.buildSessionFactory(); 
Session session = sf.openSession(); 
Transaction ts = session.beginTransaction(); 
Query query = session.createSQLQuery("select * from Tree t where pid in (select id from Tree) ").addEntity(Tree.class); //返回對象 
List  list = query.list();  

此時在遍歷list時就可以(Tree)list.get[i];將每一行的內容變換爲一個對象了。 

另還可以返回一個Map對象,也就是說在在list裏包含多個Map,代碼如下 
Query query = session.createSQLQuery("select id,name from Tree t where pid in (select id from Tree) ").setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); //返回一個map,KEY:爲DB中名稱一致(大小寫一致)遍歷list時就可以 

Map map = (Map)list.get[i]; 

map.get("id");map.get("name");來取值。按你的SQL語句select後的字段名來作爲map的Key,但這個key必須與數據庫中的字段名一模一樣。 


還可以用作函數方面的。如 
Query query = session.createSQLQuery("select sum(id) SUMID from Tree t where pid in (select id from Tree) 
.addScalar("SUMID",Hibernate.INTEGER)  //轉換類型,按DB中的type轉 
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); //返回一個map,KEY:爲DB中名稱一致(大小寫一致) 

直接就map.get("SUMID")可以取值了 


還有一點就是這個方法在Hibernate3.2版本上才能正常運行。 

================================= 
問題: 

仔細查看,發現問題在於數據類型.到網上查,發現hibernate在執行List result = session.createSQLQuery(sql).list()的時候,當SQL語句中遇到的decimal,long等類型的字段時,就出現上 面的錯誤.而且從錯誤信息中可以發現:出錯的是Dialect. 

解決辦法: 

錯誤知道以後,我就到網上找解決辦法.看來遇到這類問題的人太多了,網上到處都有人貼這個問題.我看了幾篇,發現有個解決辦法,就是自定義Hibernate Dialect.雖然所用數據庫不同(我用的數據庫是DB2),我覺得大同小異,就照着做了: 

首先建一個類,繼承org.hibernate.dialect.DB2Dialect,該類的內容如下: 

import java.sql.Types; 

import org.hibernate.Hibernate; 
import org.hibernate.dialect.DB2Dialect; 

public class PmDb2Dialect extends DB2Dialect 

public PmDb2Dialect() 

     super(); 
     registerHibernateType(Types.DECIMAL, Hibernate.BIG_DECIMAL.getName()); 



第二步,就是修改hibernate的配置文件hibernate.cfg.xml: 

將: 

     <property name="hibernate.dialect"> 
      org.hibernate.dialect.DB2Dialect 
     </property> 

改爲: 

     <property name="hibernate.dialect"> 
      com.yonder.pm.common.PmDb2Dialect 
     </property> 


=============================== 
昨天遇到問題,如下: 

ORACLE數據庫中,字段類型CHAR(8),值12345678 

hibernate中用createSQLQuery方法查詢,返回的list用object[]接收,遍歷取值發現object[0]輸出值是1,只有一位,其他的沒了。其他字段正確。 

--------------------------------------------- 

查看數據庫,發現其他字段包括VARCHAR,DATE等類型均無問題,只有char類型的出問題。 

char類型是定義長度的,8代表8個字節,節省空間並且效率要高,缺點是不靈活,長度是定死的,這裏用來定義站號,固定8位長度。所以,該數據庫這個字段類型能解決問題,但不是最好的辦法,也沒找到真正原因。 

----------------------------------------------- 

查到現在,有了一些眉目,小結如下: 

1,oracle的char字段在hibernate裏映射爲character類型,是varchar的子集。 

2,複雜SQL用createSQLQuery方法查詢沒問題,如果查詢多個字段,遍歷用object[]造型,下標從0開始輸出值,不需要映射文件;如果願意可以寫一個映射bean,方便取用。 

3,如果查詢SQL中是隻有一個字段,那就不能用object[]數組接收,只能用object類接收,直接輸出object.toString(),即是這個字段的值。 

4,可以用addScalar(String arg,Type type)方法定義要返回的字段類型,如 

s.createSQLQuery(shuiQingHQL).addScalar("STCD",Hibernate.STRING).addScalar("STNM"); 

這樣就解決了CHAR字段類型只出一位字符的問題。 

但是需要把其他字段也addScalar()進來! 

5,addScalar(String arg)裏的參數是需要大寫的!

上一篇:判斷中文的正則表達式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章