近日,在JavaEye論壇中,看了Ibatis和Hibernate的帖子,看后,心里覺(jué)得的憋悶,不說(shuō)不快, 這里,我想更細(xì)化一下:
1. 庫(kù)表的復(fù)雜度,首先取決于需求,不取決于設(shè)計(jì),設(shè)計(jì)能力強(qiáng)的人,也要遵守庫(kù)表設(shè)計(jì)的規(guī)范,從巴克斯三個(gè)范式上,原則上也要遵守。不能說(shuō)用了Hibernate,自己的庫(kù)表設(shè)計(jì)能力就強(qiáng)了。不能為了用Hibernate,就去一味批判復(fù)雜的關(guān)系不對(duì)。復(fù)雜的關(guān)系設(shè)計(jì)對(duì)不對(duì),首先取決于是否有復(fù)雜的需求,其次才取決于設(shè)計(jì)者的能力。
2. 只要你用的是關(guān)系數(shù)據(jù)庫(kù),就必須要明白,為什么叫關(guān)系數(shù)據(jù)庫(kù),而不叫面向?qū)ο髷?shù)據(jù)庫(kù),把面向?qū)ο蟮哪切┯^點(diǎn),拿到庫(kù)表設(shè)計(jì)上,后期維護(hù)和調(diào)優(yōu)上,你要擔(dān)起責(zé)任,不能讓開發(fā)人員替早期決策人員擦屁股。我見過(guò)有的人,打著OO和擴(kuò)展性的旗號(hào),硬生生的把一個(gè)表,拆成了三個(gè)表,而這三個(gè)表,本來(lái),只需要增加一個(gè)類型字段,再做一些冗余,就可以是一個(gè)表。現(xiàn)在查詢時(shí),還要把這三個(gè)表Union到一塊來(lái)查。當(dāng)需求變更時(shí),增加一個(gè)字段,不僅要改變?nèi)齻€(gè)類,還要改變?nèi)齻€(gè)表,簡(jiǎn)直是亂倫。
3.One-One的庫(kù)表設(shè)計(jì),對(duì)于DBA來(lái)講,并不是一個(gè)best practice的設(shè)計(jì)。不能為了Hibernate,刻意把大表拆成小表,再用幾個(gè)小類,做成One-One的映射關(guān)系。整體性,是不能隨便的分割,畢竟開發(fā)人在調(diào)試、測(cè)試和維護(hù)的時(shí)候,更喜歡看數(shù)據(jù)庫(kù)里的數(shù)據(jù),本來(lái)一個(gè)SQL,就查出來(lái),現(xiàn)在要到多個(gè)表中去查。
4. 增刪改存的實(shí)體維護(hù)
Ibatis比不上Hibernate,說(shuō)實(shí)在話,現(xiàn)在讓我寫SQL來(lái)維護(hù)一個(gè)多對(duì)多關(guān)系的實(shí)體維護(hù),我都要考慮上半天,別說(shuō)寫代碼了。
5. 你需要寫原生SQL嗎
首先你要確認(rèn),你項(xiàng)目的要求不需要寫原生SQL,再來(lái)講Ibatis和Hibernate的好壞,在寫原生SQL上,特別是動(dòng)態(tài)生成的SQL,ibatis比Hiberante有得一拼,ibatis就像一個(gè)模板一樣,將SQL寫在配置文件當(dāng)中,集中配置,特別方便技術(shù)領(lǐng)導(dǎo)者監(jiān)控項(xiàng)目成員寫的SQL好壞,而且沒(méi)有什么學(xué)習(xí)曲線,就寫SQL就完事了。
有人會(huì)說(shuō),Hibernate也支持寫SQL,但是寫代碼當(dāng)中,就失去了原來(lái)基于Hibernate的DAO的簡(jiǎn)潔性。那個(gè)DAO一點(diǎn)也不簡(jiǎn)潔,如果你將動(dòng)態(tài)拼SQL的代碼也放在DAO當(dāng)中,那個(gè)DAO就會(huì)充斥大量的If 。。Else。。之類的語(yǔ)句,一坨一坨的,非常的壯觀。
還有人會(huì)說(shuō),Hibernate也支持命名查詢,將SQL寫在映射文件當(dāng)中,但是命名查詢,只支持占位符固定的情況,也就是說(shuō),where a = ? and b = ? and c=?,是三個(gè)問(wèn)號(hào),就是三個(gè)問(wèn)號(hào),傳參時(shí),少一個(gè)都不行。但是很多項(xiàng)目的查詢,都是動(dòng)態(tài)的,也就是說(shuō)用戶選了這個(gè)查詢條件,才會(huì)生成這個(gè)占位符的。
Hibernate辦不到。
還有人會(huì)說(shuō),我自己用Hibernate寫一個(gè)框架,也可以做到,那你寫的可能比Ibatis好,也可能差,你要造輪子,誰(shuí)來(lái)攔不著。
5. 調(diào)優(yōu)
早期調(diào)優(yōu),有些Bad SQL,其實(shí)在code review階段,只要看看Ibatis的SQL配置文件,就可以扼殺掉的,如果使用HSQL,可能不會(huì)被發(fā)現(xiàn),因?yàn)樗粌H隱藏在代碼當(dāng)中,有的時(shí)候,還需要程序跑起來(lái),通過(guò)日志打印出SQL或者通過(guò)其它工具如P6Spy來(lái)看的出來(lái)。
后期調(diào)優(yōu),既然是調(diào)優(yōu),我想就一定是遇到了瓶頸,可能要在庫(kù)表上做冗余,可能要檢查那些Bad SQL,可能要修改代碼,可能要?jiǎng)佑肈BA層次上的一些調(diào)優(yōu)手段,那么調(diào)優(yōu)越深入,Ibatis的優(yōu)勢(shì)就越能體現(xiàn)出來(lái),比如說(shuō)增加臨時(shí)表,中間表,增加冗余字段等。
6. 開發(fā)速度
如果項(xiàng)目當(dāng)中,沒(méi)有一個(gè)Hibernate高手,你的項(xiàng)目又相對(duì)的復(fù)雜,不僅有復(fù)雜的庫(kù)表關(guān)系,還有大量的報(bào)表查詢,那么使用Hibernate,速度上遜于Ibatis.
問(wèn)題在于,怎么樣算是一個(gè)Hibernate高手,別看論壇上,那么多人,群情激奮的在說(shuō)Hibernate的好,有誰(shuí)真的是高手?
我認(rèn)識(shí)一個(gè)人,連Hibernate的命名查詢、悲觀鎖、樂(lè)觀鎖之類的,都不清楚,還在那說(shuō):“說(shuō)Hibernate不好的人,只是他不會(huì)用Hibernate,高手使用EJB也一樣用的很順溜“,我這輩子,最最討厭的就的這樣的人,人家明明用Spring很簡(jiǎn)單,很快樂(lè),為什么要用EJB,充高手。換過(guò)來(lái),項(xiàng)目使用Ibatis來(lái)做動(dòng)態(tài)查詢,很快的就解決問(wèn)題了,為什么要去學(xué)Hibernate里面高深的東東,是不是這樣就是高手了?
7. 平臺(tái)移植性
如果你的項(xiàng)目要做產(chǎn)品,而且打算基于多個(gè)數(shù)據(jù)庫(kù)平臺(tái)的發(fā)布,使用Hiberante是沒(méi)有說(shuō)了。
8. 維護(hù)性
如果不考慮移植性,Ibatis的可維護(hù)不差于Hibernate,庫(kù)表變動(dòng)引起實(shí)體類變動(dòng)時(shí),HSQL也會(huì)有改動(dòng),有人說(shuō)不用改,說(shuō)這話的那個(gè)人可能整天只會(huì)有select * ,如果ibatis也是這樣寫,也不用動(dòng)了。
HSQL好閱讀嗎,F(xiàn)rom order,確實(shí)很簡(jiǎn)單,但實(shí)際當(dāng)中,這跟拿HelloWord做例子,有什么區(qū)別?
9. 我在實(shí)際項(xiàng)目當(dāng)中的運(yùn)用
項(xiàng)目背景:
我自己從Hibernate2開始使用,我現(xiàn)在也不認(rèn)為我是Hibernate高手,我也沒(méi)有時(shí)間去鉆研Hibernate,更深的東西,我也不喜歡坐在開發(fā)人員旁邊老半天,去幫他們解決Hibernate遇到的問(wèn)題,因?yàn)槲易约哼€有很多事要做。
我的項(xiàng)目當(dāng)中,在Hibernate方面,還有一個(gè)比我更強(qiáng)的人,他也很煩去看Hibernate打印出來(lái)的sql,看上老半天,再調(diào)上老半天,項(xiàng)目進(jìn)度,嗖嗖的過(guò)去了。
水平越高的人,任務(wù)越重,很少有時(shí)間和耐心去解決一般性的問(wèn)題。
最終的運(yùn)用:
在基于Spring的容器事務(wù)管理之下,
增、刪、改、存及在事務(wù)中的查詢,使用Hibernate。
非事務(wù)性的查詢及報(bào)表,都用Ibatis,維護(hù)非常的直觀方便,開發(fā)速度上也快很多。
我覺(jué)得現(xiàn)在技術(shù)換代很快,使用一項(xiàng)技術(shù),首先是要快速的解決問(wèn)題,然后要學(xué)習(xí)他的思想,那些整天死抱著Hibernate,自認(rèn)為學(xué)習(xí)到ORM的設(shè)計(jì)技巧的人,就去繼續(xù)的學(xué)吧。
我已經(jīng)會(huì)用Hibernate的一些方面,我覺(jué)得夠用就行了,犯不上,天天鉆研HSQL,如果有時(shí)間,我覺(jué)得躺在草坪上看看Unix的編程藝術(shù),看看代碼大全,看看Oracle的編程藝術(shù),比看Hibernate的SB書要愜意多了。
簡(jiǎn)單能夠帶來(lái)快樂(lè),用過(guò)EJB,再用Spring的人,都有體會(huì),那簡(jiǎn)直是一種思想上的重生。
Ibatis的設(shè)計(jì)者認(rèn)為,在新的項(xiàng)目當(dāng)中,可以使用Hibernate,在舊的遺留項(xiàng)目當(dāng)中,可以使用Ibatis,不明白,他為什么說(shuō)這樣的話,這與新舊項(xiàng)目有什么區(qū)別? 新的項(xiàng)目就真的可以使用Hibernate嗎。