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

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

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

    歡迎使用我的 在線工具

    小D

    讀歷史、看小說、寫程序都是我所愛。技術不好,頭腦不靈光,靠的是興趣。
    隨筆 - 35, 文章 - 25, 評論 - 13, 引用 - 0
    數據加載中……

    Hibernate的筆記

    1、 left outer join 左外連接:
    左外連接的查詢結果集中包括指定左表(主表)中的所有行,
    * 而不僅僅是連接列的所有行。如果左表的某行在右表(從表)中沒有找到匹配的行,則結果
    ???? ? * 集中的右表的相對的位置為 NULL

    2、關于hibernate.hbm2ddl.auto
    ? <property name="hibernate.hbm2ddl.auto">update</property>
    ???? 將這個屬性設為 update 只有我們發生修改的時候才會重新創建表 否則不會被覆蓋掉(未理解)

    ,在SessionFactory創建時,自動檢查數據庫結構,或者將數據庫schema的DDL導出到數據庫。使用

    create-drop時,在顯式關閉SessionFactory時,將drop掉數據庫schema.
    ??????? 例如:我們將所有的表都刪除了當我們執行插入操作時,SessionFactory被創建那么會自動檢

    查數據庫scheme的DDL,建立數據表,并且會保留原來的數據,所以我們不用 Export 配置中的數據到數

    據庫,那樣會覆蓋掉所有的數據。

    3、?關于對象關系信息導出
    這里必須調用 configure 方法 否則會映射 properties 文件
    ??????? Configuration cfg = new Configuration().configure();??
    ??//用于導出用戶定義的 xml 配置信息,在數據庫中生成對應的Table
    ??SchemaExport export = new SchemaExport(cfg);
    ??export.create(true, true);

    4、* 測試lazy在class上的策略 這里默認為true
    我們在這里應當搞清session.get()和session.load()的區別
    方法load支持 lazy(在Session緩存中生成一個User的子類對象返回,只有當調用方法是才查詢) 如果

    不存在查詢的結果則拋異常
    ? ???session = HibernateUtil.getSession();
    ???tx = session.beginTransaction();
    ??????????? Classes c1 = (Classes)session.load(Classes.class, 1);
    ??????????? System.out.println("c1.getId()"+c1.getId());
    ??????????? System.out.println("c1.getName()"+c1.getName());
    這里不會發出sql語句,因為這里就采用lazy策略,所以這里采用了第三方的組件返回了一個,一個新的

    Classes 的實例(代理),只有當我們需要查詢屬性時才會發出算sql語句,在這里不會發出sql語句因為

    id 是我們輸入的。
    hibernate 支持的lazy 策略只在session的生命周期內有效。

    5、lazy在collection上的策略
    ?很顯然這些lazy都是默認的
    ????Classes c1 = (Classes)session.load(Classes.class, 1);
    ???//如果我們將集合上的lazy設為false,這里會發出兩條sql除了將要查詢的

    普通屬性查出來外,還會將非普通屬性
    ???//將集合上的lazy設為extra和true是一樣的
    ???System.out.println("c1.name= " + c1.getName());
    ???//沒有發出sql 但是會生成一個 persistent 的set作為代理
    ??????????? Set students = c1.getStudents();
    ??????????? for(Iterator it = students.iterator();it.hasNext();){
    ??????????? ?Student s = (Student)it.next();
    ??????????? ?System.out.println("student.name= " + s.getName());
    ??????????? }
    ??????????? //System.out.println("student.number= " + student.size());
    ??????????? //這里會將所有的數據讀取出來并生成對象存放在set中
    ??????????? /*這里Classes的lazy策略只對普通的屬性有關,而collection的lazy策略才對
    ???????????? * collection對象生效*/
    *測試在標簽上的lazy 策略和集合上的lazy策略一樣。
    6、one2one
    <class name="org.n2535.hibernate.Person" table="t_person">
    ? <id name="id">
    ? <!-- 這里表示了Person的主鍵是作為一個外鍵關聯了IdCard的主鍵 -->
    ???? <generator class="foreign">
    ???? <!-- 表示主鍵的生成是根據 屬性 idCard 的 id -->
    ?????? <param name="property">idCard</param>
    ???? </generator>
    ? </id>
    ? <property name="name" />
    ? <!-- 表示了Person與Idcard是一對一的關系 默認為根據主鍵加載對象(主鍵關聯) -->
    ??????? <!-- constrained(約束) (可選) 表明該類對應的表對應的數據庫表,
    ?????????????? 和被關聯的對象所對應的數據庫表之間,通過一個外鍵引用對主鍵進行約束。
    ????????????? 而且它們之間的約束條件為true
    ??????? 在這里默認了兩者的級聯操作,否則的話一方的主鍵就為空沒有任何意義了 -->
    ? <one-to-one name="idCard" constrained="true"/>
    </class>
    關于idCard的xml配置可以用
    ?? <!-- 默認為主鍵關聯 即加載cardNo 時根據其主鍵將 關聯的Person表中 主鍵相同的 元組

    取出
    ?????? 默認的抓取策略為 Join? -->
    ? <one-to-one name="person"/>

    當然也可以不用。

    7、extends
    ?<!-- 測試每個具體的類映射一種表,這里Animal應該是抽象的,所以不應該被生成出來,將

    abstract="true"-->
    <class name="Animal" abstract="true">

    ? <id name="id">
    ???? <generator class="assigned"/>
    ? </id>
    ? <!-- 此處不需要鑒別器,因為每個具體的類都生產了一張表 -->
    ? <property name="name" />
    ? <property name="sex" />
    ? <union-subclass name="Pig" table="t_pig">
    ? <property name="weight"/>
    ? </union-subclass>
    ?
    ? <union-subclass name="Bird" table="t_bird">
    ? <property name="height"/>
    ? </union-subclass>
    ?</class>?

    <!-- 測試單表繼承映射 -->
    <class name="Animal" table="t_animal" lazy="false">

    ? <id name="id">
    ???? <generator class="native"/>
    ? </id>
    ? <!-- discriminator 鑒別器,用來識別不同的子類 -->
    ? <discriminator column="type" type="string"/>
    ?
    ? <property name="name" />
    ? <property name="sex" />
    ? <!-- Pig -->
    ? <!-- discriminator-value的默認是完整的類名 -->
    ? <subclass name="Pig" discriminator-value="P">
    ??? <property name="weight"/>
    ? </subclass>
    ?
    ? <!-- Bird -->
    ? <subclass name="Bird" discriminator-value="B">
    ??? <property name="height"/>
    ? </subclass>
    ?</class>

    8、component 組件映射測試
    ?component類不是一個實體類,在hibernate中的實體是指的 一個Pojo+一個映射文件
    ??component類是一個輔助類
    ?? component 組件映射
    ? <component name="contact" class="org.n2535.hibernate.Contact">
    ??? <property name="email"/>
    ??? <property name="address"/>
    ??? <property name="zipCode"/>
    ??? <property name="contactTel"/>
    ? </component>

    9、復合主鍵
    因為主鍵是不可重復的,所以在復合主鍵的類中我們實現了Serializable接口,
    和hashcode、equals方法,能夠確保主鍵的唯一性。
    ?<!-- 復合主鍵映射我們也可以認為是一種 component 組件映射的一種? -->
    ?? <composite-id name="pk">
    ?? <key-property name="productYear"/>
    ?? <key-property name="productMonth"/>
    ?? </composite-id>
    ?? <property name="name"/>
    ?? <property name="factory"/>
    ?</class>?

    10、集合映射
    ??
    ? <set name="setValue" table="t_set_value">
    ? ?<key column="set_id"/>
    ? ?<element type="string" column="set_value"/>
    ? </set>
    ?
    ? <list name="listValue" table="t_list_value">
    ? ?<key column="list_id"/>
    ? ?<!-- 這里必須給出排序的索引,因為list是有序的(下同) -->
    ? ?<list-index column="list_index"/>
    ? ?<element type="string" column="list_value"/>
    ? </list>
    ?
    ? <array name="arrayValue" table="t_array_value">
    ? ?<key column="array_id"/>
    ? ?<list-index column="array_index"/>
    ? ?<element type="string" column="array_value"/>
    ? </array>
    ?
    ? <map name="mapValue" table="t_map_value">
    ? ?<key column="map_id"/>
    ? ?<map-key type="string" column="map_key"/>
    ? ?<element type="string" column="map_value"/>
    ? </map>

    11、關于Hibernate的鎖
    ?1)、悲觀鎖:先獲得數據庫的鎖的線程,知道該線程放棄提交,其他的線程將無法修改該數據

    (LockMode.UPGRADE :利用數據庫的for update子句加鎖。)
    2)、樂觀鎖:通常利用一個 version 的版本沖突來實現,實際上不是數據庫的鎖,一個線程的version

    必須大于數據庫中的version值才能被存儲,否則報錯。這樣提供了比悲觀鎖寬松的條件,只要 version

    大于數據庫中的version就可以被存儲,而不會因為是否死一個線程先獲得鎖,因為樂觀鎖根本就不是一

    種鎖。
    ? * 未使用悲觀鎖的時候,不同的操作可以訪問相同的數據,那么會造成數據的錯誤
    ? * 使用悲觀鎖的時候,可以避免這個問題
    可以不用顯示的調用,如果為調用update那么在提交的時候會自動的update,當第一個操作將數據鎖住

    的時候,(所有的其他訪問將被禁止)第二個select操作將會阻塞,知道第一個操作釋放了鎖,第二個

    對象的選擇操作會根據第一個對像的update的結果來讀取數據,如果兩個對象都從數據庫中讀取了相同

    的數據,那么第一次的update操作,將會被第二次的覆蓋,造成錯誤的數據。
    ?session.update(inv);
    ?要使用悲觀鎖請使用指定的數據庫的命令,或者使用hibernate中的配置。
    ? * 樂觀鎖采用的version的沖突機制,如果update的version小于或數據庫中的version
    ? * 將會產生錯誤插入失敗,一位update的限制條件是根據 主鍵和version 所以會失敗
    ? * 我們還能仿照 Hibernate 的樂觀鎖機制,用Jdbc實現樂觀鎖
    ?
    12、hibernate查詢語言hql?
    在hql中關鍵字不區分大小寫,但是屬性和類名區分大小寫

    1)、簡單屬性查詢【重要】
    ?* 單一屬性查詢,返回結果集屬性列表,元素類型和實體類中相應的屬性類型一致
    ?* 多個屬性查詢,返回的集合元素是對象數組,數組元素的類型和對應的屬性在實體類中的類型

    一致
    ?? 數組的長度取決與select中屬性的個數
    ?* 如果認為返回數組不夠對象化,可以采用hql動態實例化Student對象
    ?參見:SimplePropertyQueryTest.java?

    2)、實體對象查詢【重要】
    ?* N + 1問題,在默認情況下,使用query.iterate查詢,有可以能出現N+1問題
    ?? 所謂的N+1是在查詢的時候發出了N+1條sql語句
    ?? 1: 首先發出一條查詢對象id列表的sql
    ?? N: 根據id列表到緩存中查詢,如果緩存中不存在與之匹配的數據,那么會根據id發出相應的

    sql語句
    ?* list和iterate的區別?
    ??* list每次都會發出sql語句,list會向緩存中放入數據,而不利用緩存中的數據
    ??* iterate:在默認情況下iterate利用緩存數據,但如果緩存中不存在數據有可以能

    出現N+1問題
    ?參見:SimpleObjectQueryTest1.java/SimpleObjectQueryTest2.java
    ?
    3)、條件查詢【重要】?
    ?* 可以采用拼字符串的方式傳遞參數
    ?* 可以采用 ?來傳遞參數(索引從0開始)
    ?* 可以采用 :參數名 來傳遞參數
    ?* 如果傳遞多個參數,可以采用setParamterList方法
    ?* 在hql中可以使用數據庫的函數,如:date_format
    ?參見:SimpleConditionQueryTest.java ?
    ???
    4)、hibernate也支持直接使用sql進行查詢
    ?參見:SqlQueryTest.java

    5)、外置命名查詢
    ?* 在映射文件中采用<query>標簽來定義hql
    ?* 在程序中采用session.getNamedQuery()方法得到hql查詢串
    ?參見:Student.hbm.xml、NameQueryTest.java
    ?
    6)、查詢過濾器?
    ?* 在映射文件中定義過濾器參數
    ?* 在類的映射中使用這些參數
    ?* 在程序中啟用過濾器
    ?參見:Student.hbm.xml、FilterQueryTest.java
    ?
    7)、分頁查詢【重要】?
    ?* setFirstResult(),從0開始
    ?* setMaxResults,每頁顯示多少條數據
    ?參見:PageQueryTest.java
    ????
    8)、對象導航查詢,在hql中采用 . 進行導航【重要】
    ?參見:ObjectNavQueryTest.java
    ?
    9)、連接查詢【重要】
    ?* 內連
    ?* 外連接(左連接/右連接)?
    ?參見:JoinQueryTest.java
    ?
    10)、統計查詢【重要】
    ?參見:StatQueryTest.java
    ?
    11)、DML風格的操作(盡量少用,因為和緩存不同步)
    ?參見:DMLQueryTest.java

    13、Hibernate中的緩存
    ?1)、一級緩存
    session 中一級緩存的生命周期和session的相同
    由于load使用了session中的一級緩存 所以第二次的load 并不會發sql 因為在session的緩存中還存在

    相同的數據。
    由于get使用了session中的一級緩存 所以第二次的get 并不會發sql 因為在session的緩存中還存在相

    同的數據。
    ?? ?會發出查詢 id 的 sql(使用一級緩存才會發出) 但是不會發出查詢對象的 sql 因為Iterate

    查詢支持緩存。
    在save的時候會在緩存中保存一份當前對象的引用。
    session.clear();//全部清除
    2)、二級緩存
    ???? <!-- 指定二級緩存的提供者 -->
    ??? <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
    ??? <!-- 指定是否使用二級緩存 默認為true -->
    <property name="cache.use_second_level_cache">true</property>
    使用ehcache.xml這個配置文件來配置二級緩存。
    session 中二級緩存的生命周期和sessionFactory的相同,所以又稱為 sessionFactory 級緩存,二級

    緩存只能用于存儲實體。
    3)、三級緩存
    ??? <!-- 使用查詢緩存 默認為false-->
    ??? <property name="cache.use_query_cache">true</property>
    queryCache生命周期和sessionFactory的相同。
    但是在數據庫里面的數據改變的時候,queryCache中的對象失效。
    QueryCache的生命周期與session無關。
    Iterate 接口不支持 QueryCache。
    這里使用list 來查詢實體對象 并開啟了QueryCache 由于QueryCache 會存儲實體的主鍵值,而list 在

    查詢實體的時候不會使用緩存 所以list會使用QueryCache的實體的主鍵值 去查詢相應的,實體,由于

    它會現在緩存中查找實體對象 如果不存在則會發出sql到數據庫中查詢 這里沒有配置二級緩存 ,又重

    開了session所以在緩存中不存在實體對象 所以會根據在QueryCache 中的實體主鍵值發出sql到數據庫

    中查詢。
    因為開啟了二級緩存,QueryCache 會存儲查詢出來的實體的主鍵,而list會根據在QueryCache中的 主

    鍵值到二級緩存中查找相應的實體,所以不會發出sql(list接口不會使用一級緩存但是能夠利用這種方

    法使用QueryCache 和 二級緩存)。

    14、抓取策略
    ?1)、fetch = "select" 抓取策略 發兩個select語句;fetch = "join" 抓取策略 使用外連接

    查詢。
    2)、在集合中的抓取策略
    ??使用 load
    ? * fetch = "select" 抓取策略 發兩條sql
    ? * fetch = "join" 發一條sql 采用外連接查詢
    ?使用 HQL
    * fetch = "select" 抓取策略 發兩條sql 和加載對象方式一樣,每次每個實體的集合時會發sql
    * fetch = "subselect" 將會在查詢實體的集合時將所有查詢的實體的集合發一次sql 全部查詢出來
    3)、測試 batch – size
    ?batch-size="3"在集合中設置。

    ?

    posted on 2009-11-04 21:09 vagasnail 閱讀(307) 評論(0)  編輯  收藏 所屬分類: Java框架


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


    網站導航:
     
    主站蜘蛛池模板: 亚洲最大的黄色网| 亚洲综合精品一二三区在线| 亚洲一区二区三区乱码在线欧洲| 97公开免费视频| 中文字幕亚洲第一在线| 99久久免费中文字幕精品| 91亚洲国产在人线播放午夜| 18禁黄网站禁片免费观看不卡| 亚洲电影一区二区三区| 在线观看的免费网站无遮挡| 亚洲精品美女久久久久9999| 中文字幕免费在线看线人| 亚洲国产美女在线观看| 999国内精品永久免费观看| 亚洲精品伊人久久久久| 国产三级在线观看免费| 亚洲综合一区国产精品| 免费**毛片在线播放直播| 一级毛片高清免费播放| 国产亚洲美日韩AV中文字幕无码成人| 青青操视频在线免费观看| 亚洲资源在线视频| 天天拍拍天天爽免费视频| 亚洲丁香婷婷综合久久| 国产91精品一区二区麻豆亚洲 | 好吊妞在线成人免费| 亚洲精品国产综合久久久久紧| 亚洲毛片网址在线观看中文字幕| 中文字幕无线码中文字幕免费| 亚洲综合视频在线| 嫩草影院免费观看| 亚洲免费无码在线| 亚洲无人区视频大全| 免费乱理伦在线播放| 久久久久久成人毛片免费看| 亚洲一区二区观看播放| 国产AV无码专区亚洲AV手机麻豆| 1000部拍拍拍18勿入免费视频下载| 亚洲欧美成人一区二区三区 | 亚洲成av人片在线观看无码不卡| 1000部国产成人免费视频|