<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      NHibernate的認知,總結與陷阱

            使用NHibernate也有近三年了,從最初的2.1一直到現(xiàn)在的3.3.在使用過程中犯了很多錯誤,走了很多彎路.最近兩天又研究了一下使用細節(jié),覺得有必要將對NH的一些認知與研究成果記錄下來,作為這一段時間內的學習總結.

       

            1.認識NH

            NH并不是數據訪問層的靈丹妙藥,其只有在以代碼為中心,使用真正的面向對象/面向領域開發(fā)時才能發(fā)揮最大威力.它能讓對象以最方便,最智能的方式持久化.它不是原生Ado.Net的替代者,更不是數據庫相關技術的替代者.它嚴格遵守80/20原則,解決程序中80%的對象存儲問題.在以數據為中心的場景,如查詢,統(tǒng)計,報表等,還是使用原生Ado.Net為易.

            NH主要分為配置,映射,查詢三大塊.配置解決了數據庫連接問題.映射解決了對象與表的關聯(lián)問題.查詢解決了數據獲取問題.

            會使用NH的API離真正掌握NH還有很大距離.NH在使用中有很多陷阱,大都出現(xiàn)在查詢中,會對性能有嚴重影響.比如著名的N + 1問題,笛卡爾積問題,一次請求一次連接問題等.這要求使用者不僅會使用API,還需要了解數據庫相關知識,更需要了解代碼背后執(zhí)行的若干原理等.其它的一些陷阱則散布在配置,映射,緩存,對象狀態(tài)中等.這些給于我們的啟示是:初學者不要用,熟悉者謹慎用.要么不用,要么用好!

       

            2.相關資料

            這方面的資料首推園子里李永京大哥的兩個NH系列文章:

            NHibernate之旅系列文章導航

            NHibernate3剖析

            前者的版本號是2.1,后者是3.0.認真看完并動手試驗過后,就基本入門了.

            另外也有一些園友寫了一些研究心得或某方面的專題介紹,個人覺得這些都是不可多得的好文章.

            NHibernate實踐總結(一)

            NHibernate實踐總結(二)

            NHibernate實踐總結(三)

            NHibernate 3.x新功能實踐(一)

            NHibernate 3.x新功能實踐(二)

            NHibernate Pitfalls Index

       

            3.學習英語,努力學習英語

            不是我崇洋媚外,最新的技術資料與提問解答真心只有E文的.比如全世界最大的程序員社區(qū)StackOverflow.CSDN與它比起來真心爆弱了.我的非常多的關鍵的疑問都是在上面獲得解答的.還有各個技術框架的官網與論壇.什么Extjs, Asp.Net MVC等等.真的,如果讀的懂E文,95%的事真心就不難了.

       

            4.下載并在需要時查看源碼

            當你對于一個錯誤百思不得其解時,查看源碼就是最好的選擇.不要怕難,不要怕煩.看上去最笨的方法往往是最近的捷徑.

       

            5.關于Xml配置文件與配置硬編碼

            這兩個方面在配置,映射,查詢中均有體現(xiàn).在早期的版本中,一般都是使用Xml配置文件方式來使用NH,如數據庫配置的Hibernate.cfg.xml,對象映射的Entity.hbm.xml等,而查詢則使用類似于Sql的Hql.在最初的設想中,通過xml配置后的程序,在面臨環(huán)境變更時可以做到0編譯.如換庫,調試/日志開關,各類選項開關等.但隨著認識的深入,就發(fā)現(xiàn)其實配置太多反而適得其反:配置是不可編譯和調試的;這就意味著如果報了錯,只能人工一行一行的核對;配置是缺少智能提示的,這對使用者造成了使用困難;配置缺少合適的編輯工具與構建模型,一旦超過了一定的數據,就會讓使用者迷失在字符串的海洋中.一句話:Xml配置并不是萬能的,要學會適用而不是濫用.所以到3.0之后,乘著.Net Lambda表達式的東風,NH就推出了多種硬編碼配置:如數據庫配置就多了流配置與Lambda表達式配置,而映射則多了ConfORM,ByCode等,而查詢更是推出了IQueryOver接口.將大部分的很少變化的設定直接寫到程序中,如數據庫類型,對象映射等,而將少量開關寫入Xml配置文件中,如日志/調試開關等.

            本人目前使用的方式就是Lambda表達式配置 + ByCode映射配置 + IQueryOver查詢接口 + Web.config配置.感覺不錯~~~

       

            6.這些年我越過的那些陷阱

            a.延遲加載,抓取策略,N+1

            在上面NHibernate實踐總結(二)這篇文章里就有一些研究,再加上其它園友的教訓與實際體驗,總結就是一句話:

            大部份情況下不要在配置文件里對它進行設置,而應該在程序中一次性的顯式的獲取你所需要的數據

            默認情況下NH的Lazy=True,Fetch=Select.它的出發(fā)點很好,加載盡可能少的數據以提高性能.但這其實有非常大的局限性.對象之間是互相關聯(lián),在實際使用中很少單獨使用某一對象,而是多對象一起顯示,修改,刪除.比如最常見的顯示正在購物的客戶及其手頭的訂單,客戶可能有多個,每個客戶訂單可能有多個.如果使用默認的加載方式,加載完客戶集合后,會循環(huán)為每個客戶單獨加載自己訂單,這就是N+1問題產生的根源.當然,你可以在配置文件中設定加載客戶的同時一并加載各自的訂單.但問題在于對于其它只需客戶不需訂單的使用場影,同時被加載的訂單是多余的.所以,我得出了上面這句結論.雖然在程序中增加了若干行代碼,但這是使用可以接受的代價,獲取了最大的靈活性與最好的性能.

       

            b.查詢笛卡爾積,奇怪的重復數據

            比如對象A,同時與對象B,對象C關聯(lián).界面要同時顯示A,B,C的數據.假設A的一條,B有2條,C有3條.按照我上面的說法,顯然是加載A的同時加載B與C.下面是使用IQueryOver的語法

      session.QueryOver<A>()
      .Fetch(B).Eager
      .Fetch(C).Eager
      .SingleOrDefault()

            很好,看上去語法沒有錯.即使是使用原生的Sql也會三表直接關聯(lián)查詢.但是這卻不是性能最好的查詢.因為在返回的記錄集中,它會查出6條記錄.其中A對象部分完全重復,B對象部分重復三次,C部分重復兩次,但單看每一條記錄,卻又不是完全重復的.Ok,這就是傳說中的笛卡爾積結果!其實還有更悲劇的結果.如果在NH映射中為B與C使用的是Bag,那么你就會發(fā)現(xiàn)在查出的結果中A對象有6個B對象與6個C對象!其中B重復三次C重復兩次,與查詢結果完全一致!什么,它不會自動去重嗎?

            這個問題,我之前在看文檔看例子沒有任何在意,只有真真實實遇到了才有恍然大悟的感覺.NH給你提供了四種映射集合類型不是白給的,每一種都有它的適用范圍.對于后面一個問題,有兩種解決方法,要么在映射中使用Set,要么在程序多加一句:

      session.QueryOver<A>()
          .Fetch(B).Eager
          .Fetch(C).Eager
          .TransformUsing(Transformers.DistinctRootEntity)
          .SingleOrDefault()

            Eagerly fetch multiple collection: differences between QueryOver and Query

            對于前一個問題,只有改進查詢方式,如下:

      var aFuture = session.QueryOver<A>()
          .Fetch(B).Eager
      .TransformUsing(Transformers.DistinctRootEntity) .FutureValue(); session.QueryOver
      <A>() .Fetch(C).Eager .TransformUsing(Transformers.DistinctRootEntity) .Future(); var result = aFuture.Value;

            NHibernate - Querying relationships at depth!

            Eagerly fetch multiple collection properties (using QueryOver/Linq)?

            Eagerly fetch multiple collection: differences between QueryOver and Query

            fetching multiple nested associations eagerly using nhibernate (and queryover)

            NHibernate lazy loading nested collections with futures to avoid N+1 problem

            NHibernate Pitfalls: Eager Loading Multiple Collections

           

            c.為什么NH自動生成的查詢使用的都是Left Out Join

            說實話我一開始沒有注意這個問題,后來在碰到其它問題,想將這個連接換成Inner時才發(fā)現(xiàn)這個情況.我自己想了半天不明所以,在網上查了半天才恍然大悟:

            為了保證所有滿足條件的根對象被查出來.

            比如A對象,關聯(lián)了B對象.有些A對象有多個B對象,有些則一個沒有.當你聯(lián)合查詢所有A,B對象時你期望的結果是所有的A都能被查出,關聯(lián)了B對象則B對象有值,反之為空.如果使用Inner關聯(lián),則只會查出所有關聯(lián)了B對象的A對象.

            默認情況下這個Left Out Join連接是不可更改的.所以你如果真的想更換連接,則需要在程序設置.

            還有,只有使用了Left Out Join,Fetch設置為Join模式才會生效.而使用其它連接方式,強制使用Lazy=True,Fecth=Select,而不管你實際使用的是什么.這些都會導致N + 1問題.

            Inner or Right Outer Join in Nhibernate and Fluent Nhibernate on Many to Many collection

       

            d.多對多中奇怪的空記錄

            這個問題只有使用Xml配置方式才會出現(xiàn).因為默認提供的硬編碼根本就不給你這個選項.當然,HN都是開源的,你自己是可以改滴!

            在多對多配置中,有一個where選項,如下:

      <many-to-many where="" class="" column=""></many-to-many>

            它想表達的意思是:你可以為另一個多的一方加上Sql條件.如,我們在界面上放置的刪除按鈕,通常都是邏輯刪除,即在對象中加入一個IsDeleted字段,刪除這個對象,就是將IsDeleted字段改為True.那么我在配置NH時,會在這個where中加入"IsDeleted = 0"來過濾這些已被刪除的記錄.假設A對象多對多關聯(lián)了三個B對象,其中一個B對象的IsDeleted字段為True.在實際查詢中,會很詭異的查出三條記錄,但只有前兩條有數據,第三條為空,而其所對應的ISet集合,居然也有三個元素,但前兩個元素有值,第三個為null.

            我研究了其生成的查詢語句,它將這個Where條件放在了連接條件中,而不是最終的Where子句中.這完全不符合我的本意啊!我想這也是為什么在新的ByCode配置中將其刪除的原因.

            我現(xiàn)在的做法是,不在映射里配置,而是在程序中手工加上過濾條件.

       

            e.Many方法的Insert,Update與One方的Inverse

            這個問題也困擾了我很長時間,園子里有一篇文章寫的很好,而我也就直接說結論了.

            在Many方法設置Insert=False, Update=False,NotFound=Ignore,在One方設置Inverse=True

            [Nhibernate] Inverse

       

            f.保存的各個方法的含義

            這個問題也困擾了我很長時間,當然,園子里仍然有一篇文章寫的很好,而我也再次直接說結論了

            使用NH,大部分情況下嚴格遵守NH使用三步曲:加載,更新,保存.在大部分情況下,只需要使用Save方法.

            NHibernate的各種保存方式的區(qū)別 (save,persist,update,saveOrUpdte,merge,flush,lock)

       

            g.關聯(lián)表使用獨立主鍵

            這個也讓我煩惱了很長時間,當然,這是我自己的問題,看文檔不仔細.使用IdBag就可以解決這個問題!

            Nhibernate 3.0 cookbook學習筆記 集合

       

            h.一次請求一次連接

            我翻譯的太土了,其E文名叫One Session Per Request.我發(fā)現(xiàn)還有很多人都在自己實現(xiàn)這個功能,我也曾經試圖造過重復的輪子,但實際上NH早就自帶相關特性了.具體請參看下面這篇文章:

            NHibernate Session Management in ASP.NET MVC

            《NHibernate One Session Per Request 簡單實現(xiàn)》勘誤

       

            i.可重寫的日志

            從NH3開始,移除了對Log4Net的依賴,可以使用任意日志組件了.不過需要注意的是,NH中有很多個日志記錄器,只有名為NHibernate.SQL的日志記錄器才記錄所有生成的Sql語句.且這個名字是不可改變的!切記!下面就是幾篇參考的文章.

            Using NLog via Common.Logging with NHibernate

            How do NHibernate Profiler support NHibernate 3 logging

            Capture NHibernate generated SQL Query realtime at runtime

            Common.Logging.Elmah

            Simple logger for NHibernate 3

       

            j.擴展自己的ByCode

            這個問題是我在多對多映射中ByCode無法配置Where節(jié)所遇到的,本想通過繼承而不是修改源代碼來完成,但沒有成功.參看下面兩篇如何修改源代碼的文章吧.

            How to implement .ChildWhere() mapping with many-to-many relation in NH 3.2

            Where() clause with many-to-many relation is missing (solution in description)

            但如上面所說的,這個Where節(jié)自身有缺陷,而我最終也放棄了擴展.

       

            匆忙間已挖不出更多的坑,也想不到更多的經驗,只好擱筆于此.如果以后再想到相關內容,再自行補上.雖然用好NH不易,但這并不妨礙其成為.Net下最優(yōu)秀的ORM框架.什么iBatis啊,EF啊,都是浮云.

            向為全世界做出卓越貢獻的Hibernate框架與NHibernate框架的開發(fā)者們獻上我最崇高的敬意!你們辛苦啦!

      posted @ 2013-01-25 18:13  永遠的阿哲  閱讀(856)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 人妻少妇看a偷人无码| 日韩中文字幕高清有码| 日本少妇xxx做受| 国产精品男女午夜福利片| 色婷婷久久综合中文久久一本| 国产精品制服丝袜白丝| 久久精品国产一区二区三| 酒店大战丝袜高跟鞋人妻| 久久永久视频| 久久精品成人免费看| 中文字幕国产精品第一页| 亚洲欧美日韩愉拍自拍美利坚| 久久99精品久久久久久9| 人妻中文字幕一区二区视频| 亚洲熟妇丰满多毛xxxx| 免费A级毛片无码A∨蜜芽试看| 精品久久久久久无码不卡| 18禁极品一区二区三区| 日韩久久久久久中文人妻 | 国产欧美精品一区二区三区-老狼| 夜夜添狠狠添高潮出水| 色悠悠久久精品综合视频| 久久精品无码一区二区小草| 深夜福利资源在线观看| 中文字幕结果国产精品| 蛟河市| 久久精品熟女亚洲av麻| 精品国产免费人成网站| xxxxbbbb欧美残疾人| 欧美色欧美亚洲高清在线视频 | 91精品国产午夜福利| 日本一区不卡高清更新二区| 亚洲天堂成年人在线视频| 国产成人无码久久久精品一| 蜜臀av久久国产午夜福利软件| 产综合无码一区| 人妻少妇精品视频专区| 女同AV在线播放| 久久国产热这里只有精品| 在线中文字幕第一页| 亚洲av第二区国产精品|