隨筆-67  評(píng)論-522  文章-0  trackbacks-0
              最早接觸Hibernate是在2004年,當(dāng)時(shí)懷著忐忑和不安的心情來(lái)學(xué)習(xí)這門(mén)技術(shù)。經(jīng)過(guò)這幾年的使用和研究,也積累了一定的經(jīng)驗(yàn),下面就HQLQBC查詢(xún)來(lái)談一下我從工作中得到的一些總結(jié)。
              本文不會(huì)講什么是Hibernate、什么是ORM、更不會(huì)談怎樣使用HQLQBC。本文的目的是讓大家對(duì)平常使用最多,也是最廣泛的與數(shù)據(jù)庫(kù)打交道的兩種方式,有一個(gè)新的認(rèn)識(shí)。
              恩,如果你還不知道Hibernate,大象建議你先去學(xué)一下再來(lái)看本文,如果你已經(jīng)是這方面的高手,大可以關(guān)掉瀏覽器,千萬(wàn)不要因?yàn)楸救说挠抟?jiàn),讓你對(duì)大象口誅筆伐,進(jìn)行人身攻擊。
              HQLQBC都是查詢(xún)檢索的方式,最開(kāi)始,我一直使用的都是HQL,因?yàn)橐郧耙恢庇玫亩际?span lang="EN-US">SQL,覺(jué)得這東西和SQL差不多,上手很快。后來(lái)又用QBC,因?yàn)?span lang="EN-US">QBC
          是基于接口和類(lèi)的對(duì)象化查詢(xún),使代碼變得很清晰,很整潔。
              下面是查詢(xún)用戶(hù)表中,id2,年齡等于21,并且名字以J開(kāi)頭的兩種查詢(xún)語(yǔ)句,它們的結(jié)果都是一樣,只是不同的表現(xiàn)方式。
              HQL:
              Query query = session
                      .createQuery("from User u where u.id = 2 and u.age = 21 and u.name like 'J%'");

              List list = query.list();
              QBC
              Criteria criteria = session.createCriteria(User.class);
              List list = criteria.add(Expression.eq("id", 2)).add(
                      Expression.eq("age", 21)).add(Expression.like("name", "J%"))
                      .list();
              如果查詢(xún)?cè)購(gòu)?fù)雜一點(diǎn),需要關(guān)聯(lián)多張表,那上面這個(gè)HQL語(yǔ)句就會(huì)顯得很復(fù)雜,比較難以閱讀。對(duì)于QBC來(lái)說(shuō),需要再加一個(gè)createCriteria(),返回一個(gè)criteria新實(shí)例,比如說(shuō),用戶(hù)表與帳號(hào)表關(guān)聯(lián),需要根據(jù)帳號(hào)表中的帳號(hào),開(kāi)戶(hù)時(shí)間,金額等信息進(jìn)行查詢(xún),可以寫(xiě)成下面的形式:
          List list = criteria.add(Expression.eq("id"2)).add(
                          Expression.eq(
          "age"21)).add(Expression.like("name""J%"))
                          .createCriteria(
          "account", "a").add(
                                  Expression.eq(
          "a.account_id"112546)).add(
                                  Expression.eq(
          "a.start_date""2008-8-30")).add(
                                  Expression.eq(
          "a.money_sum"1000)).list();
              account是用戶(hù)表中建的與帳號(hào)表的關(guān)聯(lián)對(duì)象屬性,a是別名。我為了便于說(shuō)明,用的都是固定值,并且條件判斷也都是eq(等于),其實(shí)在實(shí)際開(kāi)發(fā)中,這是不可能的,這些值全都會(huì)被變量所代替。add方法也不用寫(xiě)在一起,可以分開(kāi)來(lái),特別是在查詢(xún)中,需要對(duì)傳入的參數(shù)進(jìn)行檢驗(yàn),這時(shí)就需要一個(gè)條件一個(gè)條件的往上加。
              這樣看來(lái),好像QBCHQL要好一些,大象是這么認(rèn)為的:HQL簡(jiǎn)單、靈活,QBC整潔、方便,不能說(shuō)誰(shuí)好誰(shuí)不好,否則大名鼎鼎的Hibernate為什么要支持這兩種檢索方式呢?
              根據(jù)本人做開(kāi)發(fā)的情況來(lái)看,在需要多表關(guān)聯(lián)查詢(xún)的時(shí)候,如果POJO類(lèi)之間建立一對(duì)多或多對(duì)多這樣的關(guān)聯(lián)關(guān)系,效率是很低下的,就算你設(shè)置了延遲檢索,也會(huì)感覺(jué)很慢。而且在實(shí)際開(kāi)發(fā)中,我還發(fā)現(xiàn),在數(shù)據(jù)庫(kù)中建立外鍵是一件非常吃力不討好的事情,因?yàn)楹芏鄷r(shí)候出錯(cuò)都是跟外鍵有關(guān)系,主要體現(xiàn)在修改和刪除。而POJO之間建立對(duì)象關(guān)系,則會(huì)增加編碼的復(fù)雜程度,提高出錯(cuò)機(jī)率,另外還會(huì)增加用戶(hù)等待的時(shí)間。這是大象以前開(kāi)發(fā)時(shí)所經(jīng)歷過(guò)的,所以后來(lái)的項(xiàng)目中,對(duì)于數(shù)據(jù)庫(kù)中的每個(gè)表,只給一個(gè)流水號(hào)主鍵,不在建立其它的外鍵關(guān)系,而在POJO中,只設(shè)定最原始的屬性與表中的字段對(duì)應(yīng),對(duì)于需要做多表查詢(xún)的情況,建立視圖,把需要查詢(xún)的字段屬性與要在列表中顯示的字段屬性都放在視圖POJO中,這樣,不管是HQL還是QBC,一個(gè)類(lèi)就可以解決問(wèn)題,而且對(duì)視圖查詢(xún)可比使用表之間的關(guān)聯(lián)關(guān)系查詢(xún)要快很多。
              在項(xiàng)目中,到底采取哪種檢索方式,關(guān)鍵還得看項(xiàng)目負(fù)責(zé)人。比如大象現(xiàn)在做的這個(gè)項(xiàng)目就規(guī)定了,必須使用QBC,而且除報(bào)表外,不準(zhǔn)使用視圖。呵呵,這樣的情況,只能在POJO之間建立關(guān)聯(lián)關(guān)系了,不過(guò)能少建,我們還是會(huì)盡量的減少類(lèi)之間的關(guān)聯(lián),好在現(xiàn)在開(kāi)發(fā)用的JDK5.0的,因此我們可以使用注解的方式定義一些臨時(shí)對(duì)象屬性,這樣也省掉了以前必須得寫(xiě)的hbm.xml文件,有時(shí)也采用仿視圖的方式用JavaBean來(lái)封裝一些對(duì)象和屬性。
              大家看到這里,有什么想法呢?歡迎大家提出自己寶貴的意見(jiàn),我們一起來(lái)學(xué)習(xí)和研究,共同分享成功的經(jīng)驗(yàn)。
              本文為菠蘿大象原創(chuàng),如要轉(zhuǎn)載請(qǐng)注明出處。


          posted on 2008-08-30 22:29 菠蘿大象 閱讀(4277) 評(píng)論(2)  編輯  收藏 所屬分類(lèi): Hibernate

          評(píng)論:
          # re: 小談Hibernate中的HQL與QBC查詢(xún) 2008-08-31 08:13 | johnhan2008
          對(duì)大數(shù)據(jù)量來(lái)說(shuō),hibernate關(guān)聯(lián)查詢(xún)速度上的差異確實(shí)很明顯。不過(guò)hibernate也支持原生SQL,對(duì)那些查詢(xún)速度要求比較高的,我們就可以用原生SQL呀。你說(shuō)的視圖,我也是比較支持的。  回復(fù)  更多評(píng)論
            
          # re: 小談Hibernate中的HQL與QBC查詢(xún) 2008-08-31 21:06 | 菠蘿大象
          @johnhan2008
          你說(shuō)的很對(duì),Hibernate是支持SQL方式檢索的,之所以我不談這個(gè),是因?yàn)槲覀兪褂肏ibernate,就是為了面向?qū)ο螅挥迷偃ッ鎸?duì)Table。在數(shù)據(jù)庫(kù)中調(diào)試好視圖,用它來(lái)幫助查詢(xún),可以免去再寫(xiě)繁瑣的SQL語(yǔ)句,另外,在代碼中寫(xiě)入SQL語(yǔ)句對(duì)以后的修改和維護(hù)會(huì)帶來(lái)一些不便之處。不過(guò)還是那句話(huà),關(guān)鍵看項(xiàng)目負(fù)責(zé)人采取什么方式。呵呵~~~  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 东安县| 乌拉特中旗| 泽州县| 永安市| 化德县| 丰城市| 杂多县| 衡水市| 郁南县| 桑植县| 通江县| 宾阳县| 普宁市| 绥宁县| 新安县| 阳朔县| 扬州市| 涿州市| 临潭县| 三台县| 荆州市| 准格尔旗| 平罗县| 绿春县| 黄陵县| 得荣县| 沅陵县| 乃东县| 阿鲁科尔沁旗| 汤原县| 巧家县| 乐东| 黄浦区| 铜梁县| 育儿| 呼伦贝尔市| 揭西县| 灌阳县| 雅江县| 华容县| 宜丰县|