當hibernate遇到了複雜業務的情況,不能像ibatis那麼隨意的定義sql再mapping xml檔案裡(hibernate其實也是可以的,如下:
<sql-query name="getComponentQuery">
<return alias="com" class="com.vizia.app.bo.ViewGetcomponentaclBymoduleid"/>
<![CDATA[
select main.id as {com.id},
main.code as {com.code},
main.description as {com.description},
main.component_type as {com.componentType},
main.module_id as {com.moduleId},
b.mask as {com.mask}
from (SELECT a.id,
a.code,
a.description, a.component_type, a.module_id
FROM tb_component a where a.module_id =:moduleId)main
LEFT JOIN tb_component_acl b ON main.id = b.component_id
]]>
</sql-query>
)
但是你要事先定義好一個一個BO(或者叫VO,在hibernate看來,一個bo還需要一個mapping xml),在mapping檔案裡還得指定當前mapping的table,但是寫複雜SQL,常常需要join 多張表,如何指定呢?
由此引出來一共有四種解決方案:
1.是寫一個視圖(view),然後generate一個對應的BO和mapping xml。這樣的好處,容易維護,當做資料庫方面的遷移的時候,修改的只有view的schema。但是這樣為了一次複雜查詢就得多出來兩個檔案(一個bo class一個mapping xml)。
2.就像上面說的,在mapping xml裡定義一個sql-query,這樣弊端就是常常要多張表,配置mapping檔案比較麻煩。但是維護性比寫在view裡要差一些。當做資料庫遷移的時候,需要改動xml檔案。
3.第三種是我目前個人認為是最高效率的一種方案,就是在你的DAO裡寫Native SQL--注意不是hql,做過程式員的都知道,寫比較純正的sql可以解決很多複雜業務的查詢。而hql卻有很多限制---至少在hibernate3.0還是不那麼隨意自由的。比如:這樣的不算複雜的sql想轉換成hql就比較困難:
select main.*,c.* from (select a.* from est_step_sub_cost a,
est_job_section b where b.job_section_id =a.section_id and b.header_id=?)main
left join est_step_cost c on c.step_cost_id =main.step_cost_id;
最後沒有辦法,我選擇了hibernate裡的Native sql--其實這也不是純正的sql,個人理解是一種介於sql 和hql之間的一種,如下:
StringBuffer hql =new StringBuffer(" select {main.*},{c.*} from (select a.* from est_step_sub_cost a, est_job_section b where b.header_id = ").append(headerId);
hql.append("and b.job_section_id =a.section_id)main left outer join est_step_cost c on c.step_cost_id =main.step_cost_id");
Query query = getSession().createSQLQuery(hql.toString()).addEntity("main",EstStepSubCost.class).addEntity("c",EstStepCost.class);
List list =query.list();
return list;
評價:這樣的弊端是可能跟資料庫平台依賴性比較大,在以後做資料庫遷移的時候比較麻煩,我們採取的做法,確保自己的代碼不要出現跟平台藕荷的sql,比如很多function或者Date方面的處理;好處就不用多說了。
但是使用這種方法的時候,需要注意,返回的這個list的存放的Object是一個Array,所以你需要自己處理,比如說當需要在頁面顯示的時候。
4.最後一種寫hql,這種hql我個人認為在簡單業務的處理,還能勉強湊合。複雜的還是,hql還是不夠靈活。
而且執行的效率performance是幾種當中最差的。
歡迎討論。。。。