16.1.?使用SQLQuery
對(duì)原生SQL查詢(xún)執(zhí)行的控制是通過(guò)SQLQuery接口進(jìn)行的,通過(guò)執(zhí)行Session.createSQLQuery()獲取這個(gè)接口。最簡(jiǎn)單的情況下,我們可以采用以下形式:
List cats = sess.createSQLQuery("select * from cats") .addEntity(Cat.class) .list();
這個(gè)查詢(xún)指定了:
SQL查詢(xún)字符串
查詢(xún)返回的實(shí)體
這里,結(jié)果集字段名被假設(shè)為與映射文件中指明的字段名相同。對(duì)于連接了多個(gè)表的查詢(xún),這就可能造成問(wèn)題,因?yàn)榭赡茉诙鄠€(gè)表中出現(xiàn)同樣名字的字段。下面的方法就可以避免字段名重復(fù)的問(wèn)題:
List cats = sess.createSQLQuery("select {cat.*} from cats cat") .addEntity("cat", Cat.class) .list();
這個(gè)查詢(xún)指定了:
SQL查詢(xún)語(yǔ)句,它帶一個(gè)占位符,可以讓Hibernate使用字段的別名.
查詢(xún)返回的實(shí)體,和它的SQL表的別名.
addEntity()方法將SQL表的別名和實(shí)體類(lèi)聯(lián)系起來(lái),并且確定查詢(xún)結(jié)果集的形態(tài)。
addJoin()方法可以被用于載入其他的實(shí)體和集合的關(guān)聯(lián).
List cats = sess.createSQLQuery( "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id" ) .addEntity("cat", Cat.class) .addJoin("kitten", "cat.kittens") .list();
原生的SQL查詢(xún)可能返回一個(gè)簡(jiǎn)單的標(biāo)量值或者一個(gè)標(biāo)量和實(shí)體的結(jié)合體。
Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat") .addScalar("maxWeight", Hibernate.DOUBLE); .uniqueResult();
除此之外,你還可以在你的hbm文件中描述結(jié)果集映射信息,在查詢(xún)中使用。
List cats = sess.createSQLQuery( "select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id" ) .setResultSetMapping("catAndKitten") .list();
后來(lái)我使用了命名SQL查詢(xún)方式。
16.3.?命名SQL查詢(xún)
可以在映射文檔中定義查詢(xún)的名字,然后就可以象調(diào)用一個(gè)命名的HQL查詢(xún)一樣直接調(diào)用命名SQL查詢(xún).在這種情況下,我們不 需要調(diào)用addEntity()方法.
<sql-query name="persons"> <return alias="person" class="eg.Person"/> SELECT person.NAME AS {person.name}, person.AGE AS {person.age}, person.SEX AS {person.sex} FROM PERSON person WHERE person.NAME LIKE :namePattern </sql-query>
List people = sess.getNamedQuery("persons") .setString("namePattern", namePattern) .setMaxResults(50) .list();? 這里要特別的提醒一下大家千萬(wàn)不要把主鍵忘了。剛開(kāi)始我就忘了主鍵,后來(lái)調(diào)試了半天才找出原因來(lái)。
我覺(jué)得這種發(fā)式比較好。這樣寫(xiě)出來(lái)的sql可以很整齊。我們的數(shù)據(jù)庫(kù)使用的是oracle,不過(guò)按照這上面的寫(xiě)法發(fā)現(xiàn)sql語(yǔ)句有錯(cuò)誤。
后來(lái)拿到控制臺(tái)執(zhí)行也抱錯(cuò)。因?yàn)樵瓉?lái)都用sqlserver,而sqlserver都是可以的。后來(lái)發(fā)現(xiàn)是表不能有別名改成這樣就好了。????????????SELECT?T_PAY.sys_id?as?{pay.sysId},
???????????????????T_PAY.sys_flag?as?{pay.sysFlag},
???????????????????T_PAY.sys_domain?as?{pay.sysDomain},
???????????????????T_PAY.sys_owner?as?{pay.sysOwner},
???????????????????T_PAY.sys_create_date?as?{pay.sysCreateDate},
???????????????????T_PAY.sys_update_date?as?{pay.sysUpdateDate},
???????????????????T_PAY.pay_id?as?{pay.payId},
???????????????????T_PAY.pay_name?as?{pay.payName},
???????????????????T_PAY.pay_type_id?as?{pay.payTypeId},
???????????????????T_PAY.pay_date?as?{pay.payDate},
???????????????????T_PAY.money_type_id?as?{pay.moneyTypeId},
???????????????????T_PAY.amount?as?{pay.amount},
???????????????????T_PAY.payer_id?as?{pay.payerId},
???????????????????T_PAY.payer_name?as?{pay.payerName},
???????????????????T_PAY.accept_id?as?{pay.acceptId},
???????????????????T_PAY.accept_name?as?{pay.acceptName},
???????????????????T_PAY.pay_state_id?as?{pay.payStateId},
???????????????????T_PAY.remark?as?{pay.remark}
????????????FROM???T_PAY
????????????JOIN???T_BIZ_PAY
????????????ON???????T_PAY.pay_id?=?T_BIZ_PAY.pay_id
????????????WHERE??T_BIZ_PAY.biz_id?=?:bizId
這樣在sping里面用回調(diào)查詢(xún)一下就ok了。真的很方便.
????????return?(List)getHibernateTemplate().execute(new?HibernateCallback(){
????????????public?Object?doInHibernate(Session?session)throws?HibernateException{
????????????????Query?query?=?session.getNamedQuery("find.pays.by.bizid");
????????????????query.setParameter("bizId",bizId);
????????????????return?query.list();
????????????}
????????},true);
????}