當(dāng)我們用HQL進(jìn)行子查詢的時(shí)候,如select * from Tree where pid in (select id from Tree,此時(shí)HIBERANTE就會(huì)報(bào)錯(cuò),說(shuō)什么*號(hào)錯(cuò)誤之類的。但如果將*改為Tree類里的所有子段時(shí)就不會(huì)有問(wèn)題了。就會(huì)像平時(shí)一樣第一行數(shù)據(jù)返回一個(gè)Object[],然后你再根據(jù)Tree類里字段對(duì)Object[]數(shù)組里的值進(jìn)行轉(zhuǎn)換。這樣一來(lái)比較麻煩。今天發(fā)現(xiàn)如果我SQL來(lái)查有一個(gè)方法可以返回一個(gè)對(duì)象的。 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); //返回對(duì)象 List list = query.list(); 此時(shí)在遍歷list時(shí)就可以(Tree)list.get[i];將每一行的內(nèi)容變換為一個(gè)對(duì)象了。 另還可以返回一個(gè)Map對(duì)象,也就是說(shuō)在在list里包含多個(gè)Map,代碼如下 Map map = (Map)list.get[i]; map.get("id");map.get("name");來(lái)取值。按你的SQL語(yǔ)句select后的字段名來(lái)作為map的Key,但這個(gè)key必須與數(shù)據(jù)庫(kù)中的字段名一模一樣。
直接就map.get("SUMID")可以取值了
================================= 仔細(xì)查看,發(fā)現(xiàn)問(wèn)題在于數(shù)據(jù)類型.到網(wǎng)上查,發(fā)現(xiàn)hibernate在執(zhí)行List result = session.createSQLQuery(sql).list()的時(shí)候,當(dāng)SQL語(yǔ)句中遇到的decimal,long等類型的字段時(shí),就出現(xiàn)上面的錯(cuò)誤.而且從錯(cuò)誤信息中可以發(fā)現(xiàn):出錯(cuò)的是Dialect. 解決辦法: 錯(cuò)誤知道以后,我就到網(wǎng)上找解決辦法.看來(lái)遇到這類問(wèn)題的人太多了,網(wǎng)上到處都有人貼這個(gè)問(wèn)題.我看了幾篇,發(fā)現(xiàn)有個(gè)解決辦法,就是自定義Hibernate Dialect.雖然所用數(shù)據(jù)庫(kù)不同(我用的數(shù)據(jù)庫(kù)是DB2),我覺(jué)得大同小異,就照著做了: 首先建一個(gè)類,繼承org.hibernate.dialect.DB2Dialect,該類的內(nèi)容如下: import java.sql.Types; import org.hibernate.Hibernate; public class PmDb2Dialect extends DB2Dialect 第二步,就是修改hibernate的配置文件hibernate.cfg.xml: 將: <property name="hibernate.dialect"> 改為: <property name="hibernate.dialect">
ORACLE數(shù)據(jù)庫(kù)中,字段類型CHAR(8),值12345678 hibernate中用createSQLQuery方法查詢,返回的list用object[]接收,遍歷取值發(fā)現(xiàn)object[0]輸出值是1,只有一位,其他的沒(méi)了。其他字段正確。 --------------------------------------------- 查看數(shù)據(jù)庫(kù),發(fā)現(xiàn)其他字段包括VARCHAR,DATE等類型均無(wú)問(wèn)題,只有char類型的出問(wèn)題。 char類型是定義長(zhǎng)度的,8代表8個(gè)字節(jié),節(jié)省空間并且效率要高,缺點(diǎn)是不靈活,長(zhǎng)度是定死的,這里用來(lái)定義站號(hào),固定8位長(zhǎng)度。所以,該數(shù)據(jù)庫(kù)這個(gè)字段類型能解決問(wèn)題,但不是最好的辦法,也沒(méi)找到真正原因。 ----------------------------------------------- 查到現(xiàn)在,有了一些眉目,小結(jié)如下: 1,oracle的char字段在hibernate里映射為character類型,是varchar的子集。 2,復(fù)雜SQL用createSQLQuery方法查詢沒(méi)問(wèn)題,如果查詢多個(gè)字段,遍歷用object[]造型,下標(biāo)從0開(kāi)始輸出值,不需要映射文件;如果愿意可以寫(xiě)一個(gè)映射bean,方便取用。 3,如果查詢SQL中是只有一個(gè)字段,那就不能用object[]數(shù)組接收,只能用object類接收,直接輸出object.toString(),即是這個(gè)字段的值。 4,可以用addScalar(String arg,Type type)方法定義要返回的字段類型,如 s.createSQLQuery(shuiQingHQL).addScalar("STCD",Hibernate.STRING).addScalar("STNM"); 這樣就解決了CHAR字段類型只出一位字符的問(wèn)題。 但是需要把其他字段也addScalar()進(jìn)來(lái)! 5,addScalar(String arg)里的參數(shù)是需要大寫(xiě)的! |
|