隨筆 - 42  文章 - 71  trackbacks - 0
          <2008年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          常用鏈接

          留言簿

          隨筆檔案

          文章分類

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          俺是很老土的,由于項目需要,現(xiàn)在才開始學習Hibernate。其實Hibernate剛出來的時候,只是大概了解了一下,知道這是一個O/R Mapping的框架。但是具體怎么用,能夠做到什么樣子,沒有一個具體的認識。現(xiàn)在從頭學起,按照《Hibernate參考手冊》提供的例子Step by Step做。做到Person和Event關聯(lián)的時候,手冊上給出的代碼如下:

          Session s = HibernateUtil.getSessionFactory().getCurrentSession();
          s.beginTransaction();
          Person p = (Person)s.load(Person.class, personId);
          Event e = (Event)s.load(Event.class, eventId);
          p.getEvents().add(e);
          s.getTransaction().commit();

          很簡單,很優(yōu)美的代碼哦,看起來很OO。這個代碼實現(xiàn)的需求也很簡單,就是將一個Person和一個Event關聯(lián)起來。

          但是當我看到輸出的SQL語句時就愣住了:

          Hibernate:
              select
                  person0_.id as id1_0_,
                  person0_.age as age1_0_,
                  person0_.firstname as firstname1_0_,
                  person0_.lastname as lastname1_0_
              from
                  T_PERSON person0_
              where
                  person0_.id=?
          Hibernate:
              select
                  events0_.PERSON_ID as PERSON1_1_,
                  events0_.EVENT_ID as EVENT2_1_,
                  event1_.id as id0_0_,
                  event1_.FIRE_DATE as FIRE2_0_0_,
                  event1_.title as title0_0_
              from
                  T_PERSON_EVENT events0_
              left outer join
                  T_EVENT event1_
                      on events0_.EVENT_ID=event1_.id
              where
                  events0_.PERSON_ID=?
          Hibernate:
              insert
              into
                  T_PERSON_EVENT
                  (PERSON_ID, EVENT_ID)
              values
                  (?, ?)

           

          姑且先不評價Hibernate生成的SQL語句的效率如何,就這個功能需求而言,映射到數(shù)據(jù)庫上的操作就是在T_PERSON_EVENT表中插入一行。但是Hibernate卻執(zhí)行了3個SQL語句!如果只是在寫一段Demo的代碼,這樣無所謂,但是如果是真的在有大量數(shù)據(jù)的生產(chǎn)系統(tǒng)上運行的話,我相信前面兩個SELECT語句的消耗會比最后一個INSERT語句多得多。請不要對我說:可以在硬件上優(yōu)化,可以在數(shù)據(jù)庫進行優(yōu)化。這個不是同一個問題。做為程序而言,應該是力求準確,該做的一樣都不能少,不必要的就絕對不要做。其實無論是原來的結構化編程還是現(xiàn)在的OO編程,一個函數(shù)或者一個方法,都應該是做且僅作一件事,越靠近底層邏輯的地方越應該這樣。尤其是在中國特色的系統(tǒng)中,典型的特點就是數(shù)據(jù)量大+業(yè)務復雜。在東北某省移動公司的BOSS系統(tǒng),有幾個主要的服務每天的調(diào)用量在3000萬(每個服務,他們的服務器上有大概20個這樣的服務)以上,在月底和月初的時候能夠達到5000萬甚至更高,但是服務的執(zhí)行時間保持在0.02s-0.05s之間,這個當然和數(shù)據(jù)庫設計和優(yōu)化有關,但是我無法想象如果在一件簡單的事情之外做一些不必要的事情會有怎樣的結果。在南方的某移動公司,用戶量已經(jīng)達到3000萬,他們的系統(tǒng)指導思想就是:用最簡單的技術去做最復雜的事情。

          Hibernate的擁護者會說,O/R Mapping的框架降低了程序員的門檻,不用去熟悉SQL。難道HQL就比SQL真的簡單很多么?再說了,SQL是必須的基本功,就好像能夠熟練使用操作系統(tǒng)是每個程序員的基本功一樣。因為現(xiàn)在成熟的主流數(shù)據(jù)庫都是關系型的,這是根本。這也是為什么O/R Mapping的框架運行起來總是很奇怪一樣,因為從根上是關系型的,要想轉(zhuǎn)化成OO,必然就有一些很別扭的東西。以上面的例子看,如果單純看代碼,都能夠明白是要給Person和Event建立映射,不需要其它的東西,因為personId和eventId都已經(jīng)有了。但是Hibernate不理解,他也沒有辦法理解。

          有朋友說,使用Hibernate能夠便于團隊協(xié)作。其實團隊協(xié)作也好,系統(tǒng)的可擴展性、可維護性也好,和你用不用Hibernate完全不相關。關鍵是看你的設計,能否清晰的層次化、模塊化;管理上能否協(xié)調(diào)利用資源等其它因素。

           

          我比較推崇WebLogic Workshop 8.1里面的Control/Database Control/Customer Control的設計思路(八卦一下,WebLogic Workshop的設計者之一來自MS,原來設計Visual Basic的,所以在Workshop里面有很多VBer熟悉的東西),直接在方法的上面用Annotation的方式編寫SQL語句,支持命名參數(shù)。在編譯之后成為無狀態(tài)的Session Bean。自定義Control(可以認為是業(yè)務邏輯層)負責事務控制,很好用。

          喜聞iBATIS也是這種思路的(自己寫SQL語句),看來要學學iBATIS哦。

           

          技術沒有絕對的好與壞之分,只有適合與不適合之分。我覺得Hibernate并不是很適合大型、大量數(shù)據(jù)的、復雜數(shù)據(jù)關系的應用。如果我是客戶,我需要的是一個準確滿足需求,高效、穩(wěn)定、易于擴展的系統(tǒng),我不會關心你用的是什么技術(收費的東東另當別論,呵呵)。

          以上是一個Hibernate初學者的看法,歡迎大家不吝賜教。

           

          在google這個話題的時候,看到了另外的一篇帖子,和我的想法有點接近,原文在:http://www.jdon.com/jivejdon/thread/31879.html

          作者drinkjava,內(nèi)容抄錄如下:

          注: Hibernate的復雜性是人盡皆知,想問一下Hibernate的退化用法,在JAVA***上發(fā)過這個貼子討教,http://www.java***.com/topic/82107
          ,可惜那個壇子高手太多,問題還沒看清就開始揮大棒了,只好放這里了,順便把它的一些回貼也貼在這里,望同好們指點一二:
          我用Hibernate也有半年了,感覺Hibernate的映射關系太復雜了,與懶性加載,反轉(zhuǎn)控制等結合在一起,要想控制好,實非常人之所能。個人感覺,如果不用Hibernate的關聯(lián),就把它當作關系數(shù)據(jù)庫來操作,使用和理解上都會方便不少,例如一個訂單和產(chǎn)品的配置文件寫成這樣:
          <hibernate-mapping>
            <class name="db.Order" table="orders" catalog="sample">
              <id name="id" type="java.lang.String">
                <column name="ID" length="32" />
                <generator class="uuid.hex" />
              </id>
              <property name="orderTitle" type="java.lang.String">
                <column name="ORDER_TITLE" length="30" />
              </property>
            </class>
          </hibernate-mapping>

          <hibernate-mapping>
            <class name="db.Product" table="products" catalog="sample">
              <id name="id" type="java.lang.String">
                <column name="ID" length="32" />
                <generator class="uuid.hex" />
              </id>
              <property name="productTitle" type="java.lang.String">
                <column name="PRODUCT_TITLE" length="30" />
              </property>
              <property name="orderId" type="java.lang.String">
                <column name="ORDER_ID" length="32" />
              </property>
            </class>
          </hibernate-mapping>

          操作時:
          Order o=new Order();
          o.setOrderTitle("order1");
          dao.saveOne(o);
          Product p=new Product();
          p.setProductTitle("product1");
          p.setOrderId(o.getId());
          dao.saveOne(p);
          (HQL查詢則仿照普通SQL中的寫法,此處略)


          這樣一來,純粹是用關系數(shù)據(jù)庫的思想來使用Hibernate,一個類對應一個數(shù)據(jù)庫表,表之間的約束交給數(shù)據(jù)庫的鍵來控制, 這樣一來,即得到了Hibernate的優(yōu)點:不用手工寫SQL,對象級別緩存,數(shù)據(jù)庫可移植性,也不必費力地學習和理解它了,純粹是一個薄薄的JDBC的包裝; 缺點就是不能在HQL中寫出"...object1.object2.object3..." 式的對象引用,而且關聯(lián)表的加載要自已來維護,但我認為相對于理解它復雜的配置來說,這點犧牲還是值得的, Hibernate的高級特性當然沒法用上了,但相比于直接用JDBC或用ibatis寫SQL總要好得多,只要會關系數(shù)據(jù)庫,就能立即上手,在新手多、工期短的項目中,可節(jié)省很多培訓時間,而且對于后來維護者的要求也大大降低,請問我的這種想法是否可行?

          以下為JAVA***上的回答
          引用
          java語言不是動態(tài)語言,簡化不了這些操作。activeRecord給有我們非份之想,好像馬丁大叔就在嘗試做類時的orm框架。還有jruby給了我們可行的機會

          drinkjava回答:答非所問,離題太遠。
          --------------------------------------

          引用
          不映射成類怎么利用OO思想啊,hibernate可以對一個對象進行操作,jdbc不行啊,主要是可以利用OO思想

          drinkjava回答:你根本就沒看明白這個貼子的觀點,我的意思是完全不用OO思想,只是將Hibernate當作一個比jdbc順手點的工具而已,我用關系數(shù)據(jù)庫好多年了,也開發(fā)過上百個表的應用,不用OO不也照樣做挺好?JDBC不行,可也沒人說不準用JDBC吧?

          --------------------------------------

          引用
          請再好好理解一下ORMapping的含義。
          另外不能充分發(fā)揮關聯(lián)關系的優(yōu)勢,是否是因為沒有遵循“對象模型” -> “關系模型” -> “Hibernate映射規(guī)則”的開發(fā)順序?
           

          drinkjava回答:同上,不是我沒理解,而是本來就沒打算采用“對象模型” -> “關系模型”,而是直接一個表對應一個類,走的是"關系模型"的路子。

          --------------------------------------

          引用
          不用關系影射,你用Hibernate干什么。

          drinkjava回答:

          咱笨,用不好關聯(lián)映射,怕出錯,所以干脆不用它,可關系模型咱還是很精通的,所有的關系就交給數(shù)據(jù)庫去約束它好了。至于為什么還要用Hibernate,是相比JDBC和ibatis來說的:不用寫很多SQL,有緩存,跨數(shù)據(jù)庫,支持分頁,Spring支持,總之好處一言難盡啊...

          --------------------------------------

          引用
          性能上去了,面向?qū)ο筇匦詻]有了

          drinkjava回答:

          不知你是為了OO而開發(fā),還是為了開發(fā)而OO

          --------------------------------------

          引用
          我第一次用Hibernate的時候就是這么用的
          然后涉及到多表連接時統(tǒng)統(tǒng)搞成視圖

          drinkjava回答:

          不會這么恐怖吧?Hibernate很能干的,你google一下“hibernate多表查詢”就知道了。

          --------------------------------------

          引用
          我就這樣用了快2年了,
          非常的簡便,門檻非常的低,效率也非常不錯
          級聯(lián)查詢統(tǒng)計返回object[]

          drinkjava回答:

          可見笨人不只我一個啊,這個居然用了2年。Hibernate的這種用法確實很另類,與它誕生的初衷可說是背道而馳,但事實上,這種方式程序跑起來絕對沒問題,問題是這種用法能否被團隊接受,讓我用起來心里有個底,這才是我發(fā)貼詢問的原因。光一個人私底下用,當然沒人會來說三道四,問題是能不能引入到團隊開發(fā)中,作為一種替代JDBC的簡易方案,而不是被團隊中的高手當作異已一棒子打死,因為通常一提到Hibernate大家就會聯(lián)想到ORM,這確實是一個很容易陷入的思維慣性,事實上,前面幾個回貼都是這樣,也不想想貼子要表達的是什么,就開始反駁了。

          posted on 2008-05-05 16:15 YODA 閱讀(2897) 評論(23)  編輯  收藏

          FeedBack:
          # re: Hibernate, 想說愛你不容易 2008-05-05 17:12 大牙
          呵呵~說得好~支持一下。我們之前一個BOSS項目,原來設計使用Hibernate,但是因為性能問題,到了中后期,除了使用單表維護,其他全部被JDBC替代。然后在另一個相對小型的項目中打算采用,開發(fā)了兩個月,因為性能問題,被全盤棄用。重新走直接SQL的老路。
          個人覺得,Hibernate只能在中小型系統(tǒng)中、或?qū)τ跀?shù)據(jù)處理量要求較少的系統(tǒng)比較適用。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 17:40 BeanSoft
          Hibernate的一對一,一對多,多對多一直都是謹慎用為好,尤其是大表時候的效率很低。的確,iBATIS在做SQL為中心的項目時,更合適和高效一些。你說的那個地方我能猜到,那個地方高手很多,我發(fā)了個Netbeans Struts 2插件的使用視頻發(fā)表,馬上有人來說這插件如何如何不好,好像我是作者(遺憾的是我不是插件的作者),我就得把它做成世界一流,要負責一樣。開源的軟件嘛,大家都清楚就行了,有人給做個插件都不錯了,不要搞的自己好像很熱愛開源,主要目的就是希望開源的人就得做一流的插件出來,然后自己免費用,然后自己做不了還老指責別人,甚至指責寫文章來推廣它的人。國內(nèi)的情況,大家還不都是拿著別人的東西(開源免費的和盜版的),自己一分不想花,完了還做東西來賣錢。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 18:16 jejwe
          iBATIS還是不錯的。
          畢竟myspace這個全球前幾的網(wǎng)站用的iBATIS.NET.
          我想java版本 的ib性能還是有保障的  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 20:23 26265
          Hibernate做過兩個項目,不穩(wěn)定。后來棄用了,用JDBC自己寫了一個類似的。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 20:30 YODA
          多謝各位給我更多的參考信息
          BeanSoft,你知道我說的是哪里?哈哈,那你是不是參與了那里的項目了?  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 21:48 jacky-q
          Hibernate,一開始省心,然后越來越不省心...  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 22:55 xiaohuasuper
          你的文章不錯,但你的blog太黑了,看不下去  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 23:02 YODA
          呵呵,那我改一個,謝謝你的提醒  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 23:46 BeanSoft
          呵呵 去注冊了下 為了下東西 沒參與什么項目 看來以后還是少注冊點帳號 要不然徒增麻煩 呵呵  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 23:51 iday
          把說明文檔看完再說吧。。。。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-05 23:54 sunlin
          同意 我基本是這樣想的  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-06 11:20 hammer
          一片口誅啊!我也來添一口,我做日本和歐美外包項目,從來沒聽說過那個用Hibernate的。以前公司里技術經(jīng)理也專門做過測試,Hibernate的性能在大型應用里確實比JDBC低好多。一般的做法是把sql放在一個xml或?qū)iT的class里,大家都來這里取著用。即方便查看,又可以在出了問題直接把sql粘到數(shù)據(jù)庫客戶端上運行看效果。對程序員來說,能直接看到sql是最放心的。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-06 23:40 tianya
          我覺得Hibernate很棒啊,提高效率是需要一些技巧的。一開始我也是像你們所說的那樣使用簡單的hibernate特性,后來在項目中不斷探索,針對需要提高性能的地方著重進行優(yōu)化,都能夠很好的解決性能問題。
          舉個例子吧,我一個同事用SQL實現(xiàn)一個復雜的連接幾個表的查詢,數(shù)據(jù)量大的時候,需要花費數(shù)十分鐘的時間。我使用Hibernate,再使用各種處理技巧(例如視圖、分頁、多線程、HSQL的優(yōu)化、hbm.xml特殊處理)優(yōu)化,實現(xiàn)的查詢幾乎能在半分鐘之內(nèi)顯示結果。
            回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-07 00:52 YODA
          To: tianya
          首先謝謝你的答復。不是說Hibernate就是不好,存在就是合理,Hibernate有他適用的地方。對于Hibernate的理解和掌握我肯定沒有你這么深,我想表達的意思是,Hibernate可能無法準確理解程序?qū)τ跀?shù)據(jù)操作的需求,所以做了一些無用功(要解決這個問題,估計還真是得參考drinkjava兄的Hibernate“退化”用法),所以我有點不喜歡它。說到優(yōu)化,我也相信你說的實際情況,但是拋開數(shù)據(jù)庫的優(yōu)化不說,單純的SQL優(yōu)化要比HQL和Hibernate的優(yōu)化可能更加明了和簡單呢。就像上面Hammer說的,對程序員來說,能直接看到sql是最放心的。我就是為了放心...呵呵  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-07 11:05 Cchou
          打算用這個東東的,現(xiàn)在開始猶豫了。沒有升入運用過,不敢保證自己有這個能力去優(yōu)化。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-07 12:37 anonymous
          就你這種水平,別處來現(xiàn)眼了  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-08 09:37 rain2005
          不了解hibernate就不要用,真是浪費了!  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-12 15:14 lmj
          Hibernate思想不錯~~性能方面沒有深入研究  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-05-29 13:12 碎石頭
          @tianya
          "舉個例子吧,我一個同事用SQL實現(xiàn)一個復雜的連接幾個表的查詢,數(shù)據(jù)量大的時候,需要花費數(shù)十分鐘的時間。我使用Hibernate,再使用各種處理技巧(例如視圖、分頁、多線程、HSQL的優(yōu)化、hbm.xml特殊處理)優(yōu)化,實現(xiàn)的查詢幾乎能在半分鐘之內(nèi)顯示結果。 "

          如果你那同時花上你優(yōu)化所用的一半時間來優(yōu)化他的SQL,效率應該在你的一倍以上吧?  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-06-05 13:56 flybean
          用這個例子來說Hibernate不好,不太合適。

          所產(chǎn)生的前兩句SQL,是為了獲取Person和Event實例,并不是做“無用功”。
          如果Person已經(jīng)cache在本地了,則只會產(chǎn)生insert語句,換句話說,在INSERT之前的應該是已經(jīng)存在Person實例了。

          你所想的是在已知personID和eventID的情況下,將兩者關聯(lián);而Hibernate所想的是關聯(lián)已知的Person實例和Event實例。

          作為ORM工具,Hibernate配合OO的JAVA,可以減少CRUD的工作量。但它并不能代替SQL語句。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-06-05 17:50 YODA
          感謝flybean回復

          你說的很對,后來我也在想,未必是浪費,尤其是在B/S應用中,從使用戶使用習慣和B/S應用的特點來看,可能做完INSERT還真的就是需要SELECT,Hibernate的這種特點就正好幫助我們做了這件事情了。呵呵

          [作為ORM工具,Hibernate配合OO的JAVA,可以減少CRUD的工作量。但它并不能代替SQL語句。] 這個嚴重同意,很客觀的總結。

          再次感謝。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-07-22 14:33 llmlx
          好久沒有看過Hibernate了。不過我印象中你提到的第二個sql語句是可以省略的。需要在one的一端設置inverse=true,many端設置inverse=false,也就是說將關系由多的一端維護。那樣保存的時候,不是利用p.getEvents().add(e);而是通過e.setPerson(p)。我印象中是這樣的,你可以嘗試一下。到時候再告訴我一下結果。
          對于Hibernate的使用我有一些體會,這個東西還是很強的,很多方面都考慮到了。但是,因為強所以很復雜,要想用得好必須要對其有比較深刻的理解,像延遲加載、緩存等。在使用之前一定要吃透官方提供文檔和例子,否則還是用你有把握的sql語句,雖然復雜一些,但是不會有那么多麻煩。  回復  更多評論
            
          # re: Hibernate, 想說愛你不容易 2008-12-11 23:22 benbear
          至于效率問題,可以用緩存去解決。不能因為效率就去否定hibernate。畢竟它用起來很方便。  回復  更多評論
            

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 桐梓县| 哈密市| 海淀区| 特克斯县| 积石山| 新乡县| 屏东县| 东光县| 沈阳市| 遂平县| 威远县| 武汉市| 安福县| 东山县| 北安市| 桃园市| 冷水江市| 灵璧县| 康平县| 岑巩县| 余江县| 巴林右旗| 礼泉县| 保德县| 象州县| 津南区| 寿宁县| 桂林市| 平安县| 鞍山市| 金乡县| 镇远县| 辽阳市| 嵩明县| 白水县| 奉节县| 仙桃市| 叙永县| 华容县| 宝山区| 沛县|