當我們用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)裏的參數是需要大寫的!
Hibernate的createSQLQuery查詢的小例子
上一篇:判斷中文的正則表達式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.