<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 78, comments - 34, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

             從昨晚后半夜開始下午,現(xiàn)在外面的雪還沒停,這是來北京后最大的一場雪。早上630起床,然后去吃早餐。今天是元旦假期的最后一天,幸好乘車的人不多,很快就坐上了車。如果是平時可能得在大雪里走幾站,甚至走到學(xué)校。氣溫還可以,在外面等車時,雪好美!

     

    今日繼續(xù)講解hibernate,也是hibernate課程的最后一天。Hibernate的內(nèi)容非常多,如果詳細著講估計還得兩天,但課程安排是三天。大部分之前的學(xué)生說外面用hibernate的很少!~~ 無奈!繼續(xù)上一次課程

     

    一、Hibernate的檢索策略

             上一次課程我們學(xué)習(xí)了類級別的檢索策略和關(guān)聯(lián)級別的一對多檢索策略,簡單復(fù)習(xí)一下:

    一對多關(guān)聯(lián)檢索:

    Fecth            lazy

    True

    false

    extra

    Join

    迫左

    迫左

    迫左

    Select

    延遲

    立即

    延遲(特別)

    subselect

     

     

     

     

    Fecth的優(yōu)先級別高于lazy

    延遲(特別):select count(id) from orders where cid=?

    Subselect:使用嵌套子查詢,批量查詢的時候。

     

    多對一關(guān)聯(lián)檢索:

    Fecth            lazy

    false

    proxy

    No-proxy

    Join

    迫左

    迫左

    迫左

    Select

    立即

    延遲:對端類級別是延遲

    立即:對端類級別是立即

     

    表單所屬的客戶,客戶是表單的一級關(guān)聯(lián),再取出客戶對應(yīng)的所有表單,此時表單是前一個表單的二級關(guān)聯(lián)。一級關(guān)聯(lián)、二級關(guān)聯(lián),兩次左外連接使用一條語句的話,會降低性能。所以使用了一條左邊連接查詢和一條查詢語句。這就是著名的N+1查詢。

    hibernate3.0的所有檢索策略都為延遲

     

    接下來我們繼續(xù)學(xué)習(xí)關(guān)聯(lián)級別的一對一檢索策略與多對多檢索策略。

     

    1.一對一檢索策略

             一對一關(guān)聯(lián)關(guān)系是一種什么樣的關(guān)系?一對一關(guān)系不可以把他們定義為一個類嗎?把他們放在一個表里不可以嗎?當然可以!

     

             一對一關(guān)聯(lián)兩種方案:

    1).外鍵關(guān)聯(lián),此種解決方案有兩種方法:

    老徐舉的例子,一個用戶表對應(yīng)一個地址。為什么要這么做?假設(shè)地址中包含大字段,這樣可以減少資源的浪費,提高訪問性能。

    l          方法一、就是在多對一關(guān)聯(lián)的元素節(jié)點中添加一個unique=”true”屬性便形成了一對一關(guān)聯(lián)。

    在用戶類的映射文件中添加:

    <!-- 影射一對一外鍵關(guān)聯(lián)用many-to-one進行模擬,增加唯一性約束 -->

    <many-to-one name="addr" column="aid" class="AddrFk" unique="true" />

    在地址類的映射文件中添加:

    <one-to-one name="user" property-ref="addr"/>

    l          方法二、直接使用一對一關(guān)系:

    在用戶類的映射文件中添加:

    <!-- 影射一對一主鍵關(guān)聯(lián) -->

    <one-to-one name="addr" class="AddrPk" />

    在地址類的映射文件中添加:

    <one-to-one name="user" class="UserPk" constrained="true"/>

                       同時我們需要設(shè)置地址類映射文件的主鍵為:

    <id name="id" column="id" type="integer">

        <generator class="foreign">

           <param name="property">user</param>

        </generator>

    </id>

             將用戶表的主鍵設(shè)置為地址表的外鍵。

     

    2).主鍵關(guān)聯(lián),此時子表的主鍵與主表的主鍵一一對應(yīng)。有三種解決方案:

    老徐舉了一個例子:員工有鐘點工和普通工人之分,鐘點工領(lǐng)取的是時效工資(rate),普通工人領(lǐng)取的是月薪(salary)。所以我們有必要提取一個員工的超類,并分別實現(xiàn)鐘點工和普通工人的子類。

    l          方法一、我們將鐘點工和普通工人的信息放到一個表里,需要在映射文件中添加:

    <!-- 區(qū)分符 -->

    <discriminator column="etype" type="string" length="2" />

    <property name="name" column="name" type="string" length="15" />

    <!-- 子類(整個繼承關(guān)系樹對應(yīng)于一個表) -->

    <subclass name="HeSingle" discriminator-value="he" lazy="false">

        <property name="rate" column="rate" type="float" />

    </subclass>

    <subclass name="SeSingle" discriminator-value="se" lazy="false">

        <property name="salary" column="salary" type="float" />

    </subclass>

    注意“discriminator”元素用于定義一個額外的列,用于區(qū)分員工的類型。

    l          方法二、我們?yōu)槊款悊T工都分別建一個表,如:

    <!-- 每個子類對應(yīng)一個表,從表和主表間一對一關(guān)系 -->

    <joined-subclass name="HeJoined" table="hib_hejoineds" lazy="false">

        <key column="eid" />

       <property name="rate" column="rate" type="float" />

    </joined-subclass>

          

    <joined-subclass name="SeJoined" table="hib_sejoineds" lazy="false">

        <key column="eid" />

        <property name="salary" column="salary" type="float" />

    </joined-subclass>

    column="eid"”被做為外鍵對應(yīng)主表的員工id

    l          方法三、為每類員工建立一個表,他們與主表無關(guān)各自具有全字段。但是這三個表所使用的Id是不重復(fù)的:

    <union-subclass name="HeUnion" table="hib_heunions">

        <property name="rate" column="rate" type="float" />

    </union-subclass>

    <union-subclass name="SeUnion" table="hib_seunions">

        <property name="salary" column="salary" type="float" />

    </union-subclass>

                       此時,我們需要使用一個特殊的主鍵增值生成器:

    <id name="id" column="id" type="integer">

        <generator class="hilo">

           <param name="table">hib_hilo</param>

           <param name="column">currvalue</param>

           <param name="max_lo">10</param>

        </generator>

    </id>

    "max_lo"”是id取值區(qū)間,每次插入記錄時,生成器會根據(jù)此值步長增長。如果我們執(zhí)行的一次插入操作,插入了10條記錄。那么就需要將此設(shè)置為10,以便生成器自動為我們生成10個不同的id

     

     

    2.多對多檢索策略

             在以前的學(xué)習(xí)中,我們知道多對多關(guān)聯(lián)關(guān)系需要一個中間表,用于記錄兩個多對多表的對應(yīng)主鍵。反應(yīng)到映射文件中,我們需要為兩個類添加set元素。我們依然使用,老師與學(xué)生的例子,一個老師可以有多個學(xué)生,一個學(xué)生可以有多個老師,映射文件如下:

    老師類映射文件中的set元素:

    <set name="stus" table="hib_tea_stu_links" lazy="false">

           <key column="tid" />

           <many-to-many class="Stu" column="sid" />

    </set>

    column="tid"”對應(yīng)中間表“hib_tea_stu_links”的老師外鍵。“column="sid"”對應(yīng)中間表“hib_tea_stu_links”學(xué)生的外鍵。

    學(xué)生類映射文件中的set元素:

    <set name="teas" table="hib_tea_stu_links" lazy="false" inverse="true">

           <key column="sid" />

           <many-to-many class="Tea" column="tid" />

    </set>

     

     

    檢索策略

    優(yōu)點

    缺點

    優(yōu)先考慮使用的場合

    立即檢索

    對應(yīng)用程序完全透明,不管對象處于持久化狀態(tài)還是游離狀態(tài),應(yīng)用程序都可以從一個對象導(dǎo)航到關(guān)聯(lián)的對象

    (1)select語句多

    (2)可能會加載應(yīng)用程序不需要訪問的對象,浪費許多內(nèi)存空間。

    (1)類級別

    (2)應(yīng)用程序需要立即訪問的對象

    (3)使用了二級緩存

    延遲檢索

    由應(yīng)用程序決定需要加載哪些對象,可以避免執(zhí)行多余的select語句,以及避免加載應(yīng)用程序不需要訪問的對象。因此能提高檢索性能,并節(jié)省內(nèi)存空間。

    應(yīng)用程序如果希望訪問游離狀態(tài)的代理類實例,必須保證她在持久化狀態(tài)時已經(jīng)被初始化。

    (1)一對多或者多對多關(guān)聯(lián)

    (2)應(yīng)用程序不需要立即訪問或者根本不會訪問的對象

    迫切左外連接檢索

    (1)對應(yīng)用程序完全透明,不管對象處于持久化狀態(tài)還是游離狀態(tài),都可從一個對象導(dǎo)航到另一個對象。

    (2)使用了外連接,select語句少

    (1)可能會加載應(yīng)用程序不需要訪問的對象,浪費內(nèi)存。

    (2)復(fù)雜的數(shù)據(jù)庫表連接也會影響檢索性能。

    (1)多對一或一對一關(guān)聯(lián)

    (2)需要立即訪問的對象

    (3)數(shù)據(jù)庫有良好的表連接性能。

     

    二、Hibernate的檢索方式

    Hibernate的檢索方式:

    1.對象導(dǎo)航圖:根據(jù)映射文件檢索

    2.OID檢索:根據(jù)OID檢索

    3.HQL檢索:一種類似于SQL語句的面向?qū)ο蟮?/span>hibernate檢索文本語句

    4.QBC檢索:相當于將HQL分解為一個個對象的檢索方式

    5.本地SQL檢索:SQL語句

     

             只有HQLQBC我們比較陌生,在此我們介紹一下:

    1.HQL語句

    session.createQuery("from Customer c where c.name = 'itcast' and c.age = 12");

    Customer:指向類名

    c.name:為映射文件中property元素的name

    c.ge:為映射文件中property元素的age

    看到?jīng)]有,HQL與數(shù)據(jù)庫毫無關(guān)系。HQL操作的持久化類的映射文件。

    HQL有三種查詢方式:

    1).使用參數(shù)名,如:

    //綁定參數(shù)(按照參數(shù)名稱綁定)

    q = s.createQuery("from Customer c where c.name = :a and c.age = :b");

    q.setString("a","itcast");

    q.setInteger("b",12);

    q.list();

    2).使用索引

    //綁定參數(shù)(按照參數(shù)索引位置綁定)

    q = s.createQuery("from Customer c where c.name = ? and c.age = ?");

    q.setString(0,"itcast");

    q.setInteger(1,12);

    q.list();

    3).命名查詢

    我們需要在映射文件中添加一個class的兄弟元素,這個元素可以添加在任意相關(guān)的映射文件中:

    <!-- 命名查詢 -->

    <query name="findCustomerByName">

        <![CDATA[from Customer c where c.name = ?]]>

    </query>

    我們在程序中直接調(diào)用:

    //命名查詢(將查詢條件定義到影射文件中,從影射文件中提取查詢條件)

    q = s.getNamedQuery("findCustomerByName");

    q.setString(0, "t,om");

    q.list();

     

    4).特別的左外連接查詢:

    //左外連接查詢,集合中的每個元素都是對象數(shù)組

    s.createQuery("from Customer c left outer join c.orders").list();

    //迫切左外連接查詢,集合中的每個元素都是客戶對象

    list = s.createQuery("from Customer c left outer join fetch c.orders").list();

    Set<Customer> customers = new HashSet<Customer>(list);

    左外連接查詢返回值:list中每個元素都是一個具有兩個成員的數(shù)組。數(shù)組[0]Customer對象,數(shù)組[1]Order對象。

    迫切左外連接返回值:list中每個元素都是一個Customer對象。

     

    2.QBC語句

    我們將上面的HQL語句,使用QBC來實現(xiàn):

    Criteria cra = s.createCriteria(Customer.class);

    Criterion ctn_name = Restrictions.eq("name", "itcast");

    Criterion ctn_age = Restrictions.eq("age", 12);

    //調(diào)用list時執(zhí)行查詢并返回值

    list = cra.add(ctn_name).add(ctn_age).list();

    QBC語句,一般用于動態(tài)查詢。比如,WEB應(yīng)用中的高級搜索功能!

     

    上面介紹的都是相對簡單的查詢。至于復(fù)雜的查詢,我想玩過數(shù)據(jù)庫的人一想就明白了。

     

    比較方面

    HQL檢索

    QBC檢索

    可讀性

    優(yōu)點:和sql相近,易讀

    將語句肢解成一組criteria,較差

    功能

    支持各種查詢

    不支持報表查詢和子查詢。有限的連接查詢

    查詢語句形式

    基于字符串形式的sql

    更加面向?qū)ο?/span>

    何時被解析

    運行時被解析

    編譯時被解析,更易排錯

    可擴展性

    不具擴展性

    用戶可擴展criteria接口

    對動態(tài)查詢語句的支持

    支持動態(tài)查詢,編程麻煩

    適合動態(tài)生成查詢語句

     

     

     

    三、Hibernate的映射繼承關(guān)系

    就是前邊檢索策略中提到的:

    joined-subclassunion-subclasssubclass這些元素。

     

    四、Hibernate批量操作

    使用HQLQBC等查詢語句進行批量操作

     

    五、Hibernate的緩存

             二級緩存位于SessionFactory中,用于進程范圍:多個工作單元共享,可并發(fā)訪問,可存儲實例本身也可存散列數(shù)據(jù),然后在重新組裝成對象放到一級緩存中。集群范圍:多個進程和主機間訪問,網(wǎng)絡(luò)通信是重點。需要將數(shù)據(jù)復(fù)制到所有集群中的節(jié)點。

     

    1. Hibernate緩存基礎(chǔ)

         緩存不是JPAEJB規(guī)范,用于性能優(yōu)化,不同廠商方案不同。

         緩存維護數(shù)據(jù)狀態(tài)在本地,內(nèi)存或者磁盤。

         緩存會減少數(shù)據(jù)庫訪問。

     

    2.緩存策略與范圍

         緩存類型

         .事務(wù)范圍:位于當前工作單元,不能并發(fā)訪問。

         .進程范圍:多個工作單元共享,可并發(fā)訪問,可存儲實例本身也可存散列數(shù)據(jù),然后在               重新組裝。

         .集群范圍:多個進程和主機間訪問,網(wǎng)絡(luò)通信是重點。需要將數(shù)據(jù)復(fù)制到所有集群中的節(jié)點。

     

         緩存和OID

         事務(wù)級緩存也用于對象id的使用范圍,是理想的緩存。

         進程級緩存可選擇實現(xiàn)id的進程范圍存儲,也和主鍵對應(yīng)。并發(fā)工作單元查詢同一id對象的話返     回相同的實例。在進程級緩存中的對象也可按值返回,每個工作單元再重新組裝形成副本。

     

             一級緩存是強制的,他也維護了OID,二級緩存(進程級/集群級)對某些數(shù)據(jù)來說是有用的。

     

    3.緩存的架構(gòu)

             1、一級緩存即session

         2、二級緩存是可配的插件,可用于進程/集群范圍緩存。他們緩存都是狀態(tài)(按值返回),而不是真正的持久化對象。對于特定的數(shù)據(jù)項來說緩存的并發(fā)策略定義了事務(wù)的隔離細節(jié)。每個類或者每個集合的二級緩存是可選可配的。每個緩存都使用了自己的緩存區(qū)域。

         3Hibernate還實現(xiàn)了對查詢結(jié)果集的緩存,他和二級緩存緊密結(jié)合.而且需要額外的兩個物理緩存區(qū)域來容納緩存的查詢結(jié)果和最后更新表的時間戳。

     

    1.Hibernate二級緩存

     1、所有通過同一SessionFactory開啟的會話共享同一二級緩存。

     2、對象以拆解的形式存于二級緩存中(拆解是串行化過程,算法更多,更快比java串行)

     3、重點在于緩存方案(緩存策略與物理緩存提供商)

     4、不同數(shù)據(jù)需要不同的緩存方案。涉及如下設(shè)置:

               a、是否開啟二級緩存

               bHibernate并發(fā)策略

               c、緩存過期策略(timerout LRU 內(nèi)存敏感)

               d、緩存的物理格式(內(nèi)存 索引文件 集群替換)

     

    二級緩存安裝需要兩步:

    1、決定使用哪個緩存并發(fā)策略

    2、配置緩存過期和物理緩存屬性(cache provider)

     

    2).內(nèi)置并發(fā)策略

         并發(fā)策略是調(diào)解人,負責在緩存中檢索數(shù)據(jù)。對于特定數(shù)據(jù)項,他也定義了事務(wù)隔離的語義。對類     或集合來說使用哪個并發(fā)策略需要做出判斷。

         四個內(nèi)置的并發(fā)策略體現(xiàn)了遞減的事務(wù)隔離的等級。

         1Transationsal

            只在受管環(huán)境中使用,如果需要可以確保所有的事務(wù)隔離到可重復(fù)讀,很少更新且防止臟數(shù)        據(jù)情況下該策略很重要

         2Read-write

            該策略維護讀已提交隔離級別,使用了時間戳機制只在非集群環(huán)境下使用。

         3Nostrict-read-write

            不保證在數(shù)據(jù)庫和緩存之間數(shù)據(jù)的一致性,如果使用的話,應(yīng)該配置一個高效短期的過期超        時。否則,可能讀到臟數(shù)據(jù)。

         4Read-only

            適用于從不發(fā)生改變的數(shù)據(jù)。只對數(shù)據(jù)進行引用。約束的降低帶來了性能提升。

     

         還可以實現(xiàn)自定義策略:

         orghibernatecacheCacheConcurrencyStrategy

     

    3). 選擇緩存供應(yīng)商

         Hibernate要求必須為整個應(yīng)用選擇一個供應(yīng)商。以下是開源的實現(xiàn):

         1EHCache

            適用于單個虛擬機中單個進程范圍,可緩存至內(nèi)存和磁盤,支持查詢緩存(最新版本支持集群

            緩存,未測試)

         2OpenSymphony OSCache

            在單個虛擬機中緩存至內(nèi)存或磁盤。支持豐富的過期策略和查詢緩存。

         3SwarmCache

            基于JGROUPS的集群緩存, 不支持Hibernate查詢緩存

         4JBoss Cache

            同樣基于JGROUPS廣播庫的完全事務(wù)性自我復(fù)制集群緩存,支持自我復(fù)制、校驗、同/異步

            通信、樂觀/ 悲觀鎖

     

    二級緩存講的有些快,內(nèi)部實現(xiàn)原理沒講,因為時間來不急了。至于二級緩存的詳細配置與實現(xiàn)有的是以后有時間再自學(xué)吧!

     

    今天的日志主要使用了老徐的資料,在檢索策略那塊還好,因為講的比較細。之后的主要就是緩存技術(shù),一級緩存學(xué)的挺好,就這個二級緩存留有些“懸念”。

     

             老徐是一位優(yōu)秀的老師,傳智播客確實很牛。能留住這么多人才!

     

             明天就開始學(xué)習(xí)luncene了,期待它的到來!

     

             加油!


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲av中文无码字幕色不卡| 国产午夜亚洲精品不卡电影| 免费人成在线观看播放a| A级毛片高清免费视频在线播放| 男人的好看免费观看在线视频 | 免费观看a级毛片| 亚洲精品无码mv在线观看网站| 亚洲国产品综合人成综合网站| 九九九精品视频免费| 99在线精品视频观看免费| 亚洲一区精品伊人久久伊人| 亚洲六月丁香六月婷婷蜜芽 | 美女裸身网站免费看免费网站| 亚洲欧洲日产国码高潮αv| 亚洲一区二区三区高清视频| 99在线免费观看| 国产嫩草影院精品免费网址| 亚洲丝袜美腿视频| 特级做a爰片毛片免费看| 精品久久久久成人码免费动漫| 亚洲桃色AV无码| 香蕉视频在线观看免费| 真人做人试看60分钟免费视频| 亚洲国产另类久久久精品小说| 亚洲欧洲精品成人久久曰| 欧洲人免费视频网站在线| 亚洲国产电影av在线网址| 亚洲一卡2卡3卡4卡乱码 在线| 久久狠狠躁免费观看| 亚洲第一区在线观看| 中日韩亚洲人成无码网站| 免费精品无码AV片在线观看| 国产精品亚洲产品一区二区三区| 日本亚洲色大成网站www久久| 曰批全过程免费视频播放网站| 久久夜色精品国产亚洲| 草久免费在线观看网站| 日韩激情淫片免费看| 亚洲人xxx日本人18| 182tv免费观看在线视频| 亚洲精品乱码久久久久久自慰|