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()進來!
 java

相關文章
相關標籤/搜索