Hibernate映射配置文件詳解
《Hibernate映射配置文件詳解》由會員分享,可在線閱讀,更多相關(guān)《Hibernate映射配置文件詳解(80頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、映射文件詳解映射文件詳解目標(biāo)目標(biāo) 學(xué)習(xí)Hibernate的配置文件(hibernate.cfg.xml) 學(xué)習(xí)Hibernate的映射聲明(*.hbm.xml)HibernateHibernate配置文件配置文件 Hibernate配置文件主要用于配置數(shù)據(jù)庫連接和 Hibernate 運(yùn)行時所需的各種屬性 每個 Hibernate 配置文件對應(yīng)一個 Configuration 對象。 Hibernate配置文件可以有兩種格式: hibernate.properties hibernate.cfg.xml hibernate.cfg.xml的常用屬性 connection.url:數(shù)據(jù)庫URL
2、connection.username:數(shù)據(jù)庫用戶名 connection.password:數(shù)據(jù)庫用戶密碼 connection.driver_class:數(shù)據(jù)庫JDBC驅(qū)動 show_sqlshow_sql:是否將運(yùn)行期生成的SQL輸出到日志以供調(diào)試。取值 true | false dialectdialect:配置數(shù)據(jù)庫的方言,根據(jù)底層的數(shù)據(jù)庫不同產(chǎn)生不同的sql語句,Hibernate 會針對數(shù)據(jù)庫的特性在訪問時進(jìn)行優(yōu)化。 hbm2ddl.autohbm2ddl.auto:在啟動和停止時自動地創(chuàng)建,更新或刪除數(shù)據(jù)庫模式。取值 create | update | create-drop
3、mapping resourcemapping resource:映射文件配置,配置文件名必須包含其相對于根的全路徑 connection.datasource :JNDI數(shù)據(jù)源的名稱 jdbc.fetch_size jdbc.fetch_size 和和 jdbc.batch_sizejdbc.batch_sizejdbc.fetch_sizejdbc.fetch_size:實(shí)質(zhì)是調(diào)用:實(shí)質(zhì)是調(diào)用 Statement.setFetchSize() Statement.setFetchSize() 方法設(shè)定方法設(shè)定JDBCJDBC的的StatementStatement讀取數(shù)據(jù)的時候每次從數(shù)據(jù)庫
4、中取出的記錄條數(shù)。例如一讀取數(shù)據(jù)的時候每次從數(shù)據(jù)庫中取出的記錄條數(shù)。例如一次查詢次查詢1 1萬條記錄,對于萬條記錄,對于OracleOracle的的JDBCJDBC驅(qū)動來說,是不會驅(qū)動來說,是不會 1 1 次性把次性把1 1萬條取萬條取出來的,而只會取出出來的,而只會取出Fetch SizeFetch Size條數(shù),當(dāng)紀(jì)錄集遍歷完了這些記錄以后,條數(shù),當(dāng)紀(jì)錄集遍歷完了這些記錄以后,再去數(shù)據(jù)庫取再去數(shù)據(jù)庫取Fetch SizeFetch Size條數(shù)據(jù)。因此大大節(jié)省了無謂的內(nèi)存消耗。當(dāng)然條數(shù)據(jù)。因此大大節(jié)省了無謂的內(nèi)存消耗。當(dāng)然Fetch SizeFetch Size設(shè)的越大,讀數(shù)據(jù)庫的次數(shù)越少
5、,速度越快;設(shè)的越大,讀數(shù)據(jù)庫的次數(shù)越少,速度越快;Fetch SizeFetch Size越小,越小,讀數(shù)據(jù)庫的次數(shù)越多,速度越慢。讀數(shù)據(jù)庫的次數(shù)越多,速度越慢。OracleOracle數(shù)據(jù)庫的數(shù)據(jù)庫的JDBCJDBC驅(qū)動默認(rèn)的驅(qū)動默認(rèn)的Fetch Fetch Size=10Size=10,是一個保守的設(shè)定,根據(jù)測試,當(dāng),是一個保守的設(shè)定,根據(jù)測試,當(dāng)Fetch Size=50Fetch Size=50的時候,性能的時候,性能會提升會提升1 1倍之多,當(dāng)倍之多,當(dāng)Fetch Size=100Fetch Size=100,性能還能繼續(xù)提升,性能還能繼續(xù)提升20%20%,F(xiàn)etch SizeFe
6、tch Size繼續(xù)增大,性能提升的就不顯著了。建議使用繼續(xù)增大,性能提升的就不顯著了。建議使用OracleOracle時將時將Fetch SizeFetch Size設(shè)到設(shè)到5050。并不是所有的數(shù)據(jù)庫都支持。并不是所有的數(shù)據(jù)庫都支持Fetch SizeFetch Size特性,例如特性,例如MySQLMySQL就不支持。就不支持。MySQLMySQL就像上面那種最壞的情況,總是一下就把就像上面那種最壞的情況,總是一下就把1 1萬條記錄完全取出來,內(nèi)萬條記錄完全取出來,內(nèi)存消耗會非常非常驚人!這個情況就沒有什么好辦法了存消耗會非常非常驚人!這個情況就沒有什么好辦法了hibernate.jdb
7、c.batch_sizehibernate.jdbc.batch_size:設(shè)定對數(shù)據(jù)庫進(jìn)行批量刪除,批量更新和批:設(shè)定對數(shù)據(jù)庫進(jìn)行批量刪除,批量更新和批量插入的時候的批次大小,有點(diǎn)相當(dāng)于設(shè)置量插入的時候的批次大小,有點(diǎn)相當(dāng)于設(shè)置BufferBuffer緩沖區(qū)大小的意思。緩沖區(qū)大小的意思。Batch SizeBatch Size越大,批量操作的向數(shù)據(jù)庫發(fā)送越大,批量操作的向數(shù)據(jù)庫發(fā)送sqlsql的次數(shù)越少,速度就越快。的次數(shù)越少,速度就越快。測試結(jié)果是當(dāng)測試結(jié)果是當(dāng)Batch Size=0Batch Size=0的時候,使用的時候,使用HibernateHibernate對對OracleOra
8、cle數(shù)據(jù)庫刪除數(shù)據(jù)庫刪除1 1萬條記錄需要萬條記錄需要2525秒,秒,Batch Size = 50Batch Size = 50的時候,刪除僅僅需要的時候,刪除僅僅需要5 5秒!可見有秒!可見有多么大的性能提升!多么大的性能提升!OracleOracle數(shù)據(jù)庫數(shù)據(jù)庫 Batch Size = 30 Batch Size = 30 的時候比較合適。的時候比較合適。這兩個選項非常重要,將嚴(yán)重影響這兩個選項非常重要,將嚴(yán)重影響HibernateHibernate的的CRUD(create,read,update,delete)CRUD(create,read,update,delete)性能性能
9、! !配置 c3p0數(shù)據(jù)庫連接池 c3p0連接池是Hibernate推薦使用的連接池,若需要使用該連接池時,需要將c3p0的jar包拷貝到 WEB-INF 的 lib 目錄下 POJO 類和數(shù)據(jù)庫的映射文件*.hbm.xml POJO 類和關(guān)系數(shù)據(jù)庫之間的映射可以用一個XML文檔(XML document)來定義。映射按照POJO的定義來創(chuàng)建,而非表的定義。 通過 POJO 類的數(shù)據(jù)庫映射文件,Hibernate可以理解持久化類和數(shù)據(jù)表之間的對應(yīng)關(guān)系,也可以理解持久化類屬性與數(shù)據(jù)庫表列之間的對應(yīng)關(guān)系映射文件示例映射文件說明 hibernate-mapping 類層次:Class 主鍵。id 基
10、本類型:property 自定義類:many-to-one | one-to-one 集合:set | list | map | array one-to-many many-to-many 子類:subclass | joined-subclass 其它:component | any等 查詢語句:query(用來放置查詢語句,便于對數(shù)據(jù)庫查詢的統(tǒng)一管理和優(yōu)化)注意:一個Hibernate-mapping中可以同時定義多個類。hibernate-mapping hibernate-mapping hibernate-mapping 是是 hibernate hibernate 映射文件的根元
11、素映射文件的根元素schema (schema (可選可選): ): 數(shù)據(jù)庫數(shù)據(jù)庫schemaschema的名稱。的名稱。catalog (catalog (可選可選): ): 數(shù)據(jù)庫數(shù)據(jù)庫catalogcatalog的名稱。的名稱。 default-cascade (default-cascade (可選可選 - - 默認(rèn)為默認(rèn)為 none): none): 默認(rèn)的級聯(lián)風(fēng)格。默認(rèn)的級聯(lián)風(fēng)格。 default-access (default-access (可選可選 - - 默認(rèn)為默認(rèn)為 property): Hibernateproperty): Hibernate用來訪問屬性的用來訪問屬性
12、的策略??梢酝ㄟ^實(shí)現(xiàn)策略??梢酝ㄟ^實(shí)現(xiàn)PropertyAccessorPropertyAccessor接口自定義。接口自定義。 default-lazy (default-lazy (可選可選 - - 默認(rèn)為默認(rèn)為 true): true): 指定了未明確注明指定了未明確注明lazylazy屬性的屬性的JavaJava屬性和集合類,屬性和集合類, HibernateHibernate會采取什么樣的默認(rèn)加載風(fēng)格。會采取什么樣的默認(rèn)加載風(fēng)格。 auto-import (auto-import (可選可選 - - 默認(rèn)為默認(rèn)為 true): true): 指定我們是否可以在查詢語言中使指定我們是否可
13、以在查詢語言中使用非全限定的類名(僅限于本映射文件中的類)。用非全限定的類名(僅限于本映射文件中的類)。 package (package (可選可選): ): 指定一個包前綴,如果在映射文檔中沒有指定全限定的指定一個包前綴,如果在映射文檔中沒有指定全限定的類名,類名, 就使用這個作為包名。就使用這個作為包名。 class ClassClass:定義一個持久化類:定義一個持久化類 name (name (可選可選): ): 持久化類(或者接持久化類(或者接口)的類名口)的類名table (table (可選可選 - - 默認(rèn)是類的非全限默認(rèn)是類的非全限定名定名): ): 對應(yīng)的數(shù)據(jù)庫表名對應(yīng)的
14、數(shù)據(jù)庫表名discriminator-value (discriminator-value (可選可選 - - 默默認(rèn)和類名一樣認(rèn)和類名一樣): ): 一個用于區(qū)分不一個用于區(qū)分不同的子類的值,在多態(tài)行為時使用。同的子類的值,在多態(tài)行為時使用。它可以接受的值包括它可以接受的值包括 null null 和和 not not nullnull。 主鍵-id IdId:被映射的類必須定義對應(yīng)數(shù)據(jù)庫表主鍵字段。大多數(shù)類有一個:被映射的類必須定義對應(yīng)數(shù)據(jù)庫表主鍵字段。大多數(shù)類有一個JavaBeanJavaBean風(fēng)格的屬性,風(fēng)格的屬性, 為每一個實(shí)例包含唯一的標(biāo)識。為每一個實(shí)例包含唯一的標(biāo)識。 元素定義
15、了元素定義了該屬性到數(shù)據(jù)庫表主鍵字段的映射。該屬性到數(shù)據(jù)庫表主鍵字段的映射。 name (name (可選可選): ): 標(biāo)識持久化類屬性的名字。標(biāo)識持久化類屬性的名字。 type (type (可選可選): ): 標(biāo)識標(biāo)識HibernateHibernate類型的名字。類型的名字。 column (column (可選可選 - - 默認(rèn)為屬性名默認(rèn)為屬性名): ): 主鍵字段的名字。主鍵字段的名字。主鍵生成策略主鍵生成策略generatorgenerator 可選的子元素是一個Java類的名字, 用來為該持久化類的實(shí)例生成唯一的標(biāo)識。如果這個生成器實(shí)例需要某些配置值或者初始化參數(shù), 用元素來
16、傳遞。 主鍵生成策略主鍵生成策略generatorgenerator 所有的生成器都實(shí)現(xiàn)org.hibernate.id.IdentifierGenerator接口。某些應(yīng)用程序可以選擇提供他們自己特定的實(shí)現(xiàn)。當(dāng)然, HibernateHibernate提供了很多內(nèi)置的實(shí)現(xiàn)提供了很多內(nèi)置的實(shí)現(xiàn): : 推薦使用推薦使用基本類型property propertyproperty:為類定義了一個持久化的:為類定義了一個持久化的, ,JavaBeanJavaBean風(fēng)格的屬性風(fēng)格的屬性 name: name: 屬性的名字屬性的名字, ,以小寫字母開頭。以小寫字母開頭。 column (column (
17、可選可選 - - 默認(rèn)為屬性名字默認(rèn)為屬性名字): ): 對應(yīng)的數(shù)據(jù)庫字段名。對應(yīng)的數(shù)據(jù)庫字段名。 type (type (可選可選): ): 一個一個HibernateHibernate類型的名字。類型的名字。 lazy (lazy (可選可選 - - 默認(rèn)為默認(rèn)為 false): false): 指定實(shí)例變量第一次被訪問時,這個屬性指定實(shí)例變量第一次被訪問時,這個屬性是否延遲抓?。ㄊ欠裱舆t抓?。╢etched lazilyfetched lazily)。)。 unique (unique (可選可選): ): 為該字段添加唯一的約束。為該字段添加唯一的約束。not-null (not-nu
18、ll (可選可選):):為該字段添加非空約束。為該字段添加非空約束。 optimistic-lock (optimistic-lock (可選可選 - - 默認(rèn)為默認(rèn)為 true): true): 指定這個屬性在做更新時是否指定這個屬性在做更新時是否需要獲得樂觀鎖定(需要獲得樂觀鎖定(optimistic lockoptimistic lock)。)。HibernateHibernate內(nèi)置映射類型內(nèi)置映射類型 HibernateHibernate內(nèi)置映射類型內(nèi)置映射類型 映射集合屬性 集合屬性大致有兩種: 單純的集合屬性,如像List、Set或數(shù)組等集合屬性 Map結(jié)構(gòu)的集合屬性,每個屬性值
19、都有對應(yīng)的Key映射 集合映射的元素大致有如下幾種: list:用于映射List集合屬性 set:用于映射Set集合屬性 map:用于映射Map集合性 array:用于映射數(shù)組集合屬性 bag:用于映射無序集合 idbag:用于映射無序集合,但為集合增加邏輯次序 List集合映射 List是有序集合,因此持久化到數(shù)據(jù)庫時也必須增加一列來表示集合元素的次序??聪旅娴某志没?,該News類有個集合屬性:schools,該屬性對應(yīng)學(xué)校。而集合屬性只能以接口聲明,因此下面代碼中,schools的類型能是List,不能是ArrayList,但該集合屬性必須使用實(shí)現(xiàn)類完成初始化。 List集合映射 在作相
20、應(yīng)映射時,list元素要求用list-index的子元素來映射有序集合的次序列。集合的屬性的值會存放有另外的表中,不可能與持久化類存儲在同一個表內(nèi)。因此須以外鍵關(guān)聯(lián),用Key元素來映射該外鍵列。 List集合映射 測試程序:List集合映射 生成的表及插入的數(shù)據(jù): person_tableList集合映射 生成的表及插入的數(shù)據(jù): school_tableSet集合映射 Set集合屬性映射與List非常相似,但因為Set是無序的,不不可重復(fù)可重復(fù)的集合。因此set元素?zé)o須使用index元素來指定集合元素次序。映射文件與List相似,區(qū)別在于使用set元素時,無須增加index列來保存集合的次序
21、Set集合映射 測試程序Set集合映射 生成的表及插入的數(shù)據(jù): school_table注:映射注:映射 Set Set 集合屬性時,如果集合屬性時,如果 element element 元素包括元素包括 not-null = not-null = “truetrue” 屬性,則集合屬性表以關(guān)聯(lián)持久化類的外鍵和元素列作為聯(lián)合主鍵,否則該屬性,則集合屬性表以關(guān)聯(lián)持久化類的外鍵和元素列作為聯(lián)合主鍵,否則該表沒有主鍵。但表沒有主鍵。但 List List 集合屬性不會,集合屬性不會,List List 集合屬性總是以外鍵列和元素集合屬性總是以外鍵列和元素此序列作為聯(lián)合主鍵。此序列作為聯(lián)合主鍵。bag
22、元素映射 bag元素既可以為List集合屬性映射,也可以為Collection集合屬性映射。不管是哪種集合屬性,使用bag元素都將被映射成無序集合,而集合屬性對應(yīng)的表沒有主鍵。Bag 元素只需要 key 元素來映射外鍵列,使用 element 元素來映射集合屬性的每個元素。 Map集合屬性 Map不僅需要映射屬性值,還需要映射屬性Key。映射Map集合屬性時,同樣需要指定外鍵列,同時還必須指定Map的Key列。系統(tǒng)將以外鍵列和Key列作為聯(lián)合主鍵。 Map集合屬性使用map元素映射時,該map元素需要key和map-key兩個子元素。其中key子元素用于映射外鍵列,而map-key子元素則用于
23、映射Map集合的Key。而map-key和element元素都必須確定type屬性 集合屬性的性能的分析 對于集合屬性,通常推薦使用延遲加載策略延遲加載策略。所謂延遲加載就是當(dāng)系統(tǒng)需要使用集合屬性時才從數(shù)據(jù)庫裝載關(guān)聯(lián)的數(shù)據(jù)。Hibernate對集合屬性默認(rèn)采用延遲加載,在某些特殊的情況下為set,,list,map等元素設(shè)置lazy=“false”屬性來取消延遲加載。 可將集合分成如下兩類: 有序集合:集合里的元素可以根據(jù)Key或Index訪問 無序集合:集合里的元素中只能遍歷 有序集合擁有由 key 和 index 組成的聯(lián)合主鍵,集合的屬性在增加、刪除及修改中擁有較好的性能表現(xiàn) - 主鍵已
24、經(jīng)被有效的索引,因此 Hibernate 可以迅速的找到該行數(shù)據(jù)。 映射Set集合屬性時,如果element元素包括not-null=not-null=“truetrue”屬性,則集合屬性表以關(guān)聯(lián)持久化類的外鍵和元素列作為聯(lián)合主鍵,否則該表沒有主鍵,因此性能較差。 在設(shè)計較好的Hiberate domain Object中,集合屬性通常都會增加inverse=“true”的屬性,此時集合端不再控制關(guān)聯(lián)關(guān)系。因此無需考慮集合的更新性能。 映射組件屬性 組件屬性的意思是持久化類的屬性既不是基本數(shù)據(jù)類型,也不是 String 字符串,而是某個組件變量,該組件屬性的類型可以是自定義類。映射組件屬性 顯
25、然無法直接用 property 映射 name 屬性。為了映射組件屬性, Hibernate 提供了 component 元素。每個 component 元素映射一個組件屬性,組件屬性必須指定該屬性的類型,component 元素中的 class 屬性用于確定組件的類型。 映射組件屬性 測試程序映射組件屬性 生成的表及插入的數(shù)據(jù): worker_table集合組件屬性映射 集合除了存放 String 字符串以外,還可以存放組件類型。實(shí)際上,更多情況下,集合組件存放的都是組件類型。集合組件屬性映射對于有集合屬性對于有集合屬性 POJOPOJO, 需要使用需要使用 set, list, bag s
26、et, list, bag 等集合元素來映射集合屬性。等集合元素來映射集合屬性。如果集合里的元素是普通字符串,則使用如果集合里的元素是普通字符串,則使用 element element 映射集合元素即可。如果集合映射集合元素即可。如果集合元素也是定義類,則需使用元素也是定義類,則需使用 composite-element composite-element 子元素來映射集合元素。子元素來映射集合元素。composite-element composite-element 元素映射一個組件類型,因此需要元素映射一個組件類型,因此需要 class class 元素確定元素的類元素確定元素的類型,該
27、元素還支持型,該元素還支持 property property 的子元素來定義組件類型的子屬性的子元素來定義組件類型的子屬性Hibernate 的關(guān)聯(lián)關(guān)系映射 客觀世界中的對象很少有孤立存在的。關(guān)聯(lián)關(guān)系是面向?qū)ο蠓治觯嫦驅(qū)ο笤O(shè)計最重要的知識。關(guān)聯(lián)關(guān)系大致有如下兩個分類: 單向關(guān)系:只需要單向訪問關(guān)聯(lián)端 單向 1-1 單向 1-N(不推薦使用) 單向 N-1 單向 N-N 雙向關(guān)系:關(guān)聯(lián)的兩端可以相互訪問 雙向 1-1 雙向 1-N 雙向 N-N單向 N-1 單向 N-1 關(guān)聯(lián)只需從 N 的一端可以訪問 1 的一端。模型:多個人(Person)對應(yīng)同一個地址(Address)。只需要從人實(shí)體端
28、找到相應(yīng)的地址實(shí)體。無須關(guān)心從某個地址找到全部住戶。 單向 N-1 Person 端增加了 Address 屬性,該屬性不是一個普通的組件屬性,而是引用了另外一個持久化類,使用 many-to-onemany-to-one 元素映射 N-1 的持久化屬性。 many-to-one 元素的作用類似于 property 元素,用于映射持久化類的某個屬性,區(qū)別是改元素映射的是關(guān)聯(lián)持久化類。與 property 元素類似,many-to-one 元素也必須擁有 name 屬性,用于確定該屬性的名字,column 屬性確定外鍵列的列名外鍵列的列名.單向 N-1 生成的表 person_table Add
29、ress_table基于外鍵的單向 1-1 單向 1-1,POJO 與 N-1 沒有絲毫區(qū)別。 基于外鍵的單向 1-1 映射文件:只需要在原有的 many-to-one 元素添加 unique=“true”,用以表示 N 的一端必須唯一即可,N的一端增加了唯一約束, 即成為單向 1-1. person_table基于主鍵的單向 1-1 基于主鍵關(guān)聯(lián)的持久化類不能擁有自己的主鍵生成器,它的主鍵由關(guān)聯(lián)類負(fù)責(zé)生成。增加one-to-one元素來映射關(guān)聯(lián)屬性,必須為one-to-one元素增加constrained=true屬性,表明該類的主鍵由關(guān)聯(lián)類生成。基于主鍵的單向 1-1 person_tab
30、le單向的 1-N 單向 1-N 關(guān)聯(lián)的 POJO 需要使用集合屬性。因為一的一端需要訪問 N 的一端,而 N 的一端將以集合的形式表現(xiàn)。 不推薦使用單向的 1-N 關(guān)聯(lián): 使用 1 的一端控制關(guān)聯(lián)關(guān)系時,會額外多出 update 語句。 插入數(shù)據(jù)時無法同時插入外鍵列,因而無法為外鍵列添加非空約束單向的 N-N 單向 N-N,POJO 與 1-N 沒有絲毫區(qū)別。 與映射集合屬性類似,必須為set,list等集合元素添加 key 子元素,用以映射關(guān)聯(lián)的外鍵列。與集合映射不同的是,建立 N-N 關(guān)聯(lián)時,集合中的元素使用 many-to-many,而不是使用 element 子元素 N-N 的關(guān)聯(lián)必
31、須使用連接表。單向的 N-N 的測試程序單向的 N-N 生成的表及插入的數(shù)據(jù): address_table person_table person_address_table雙向 1-N 對于 1-N 的關(guān)聯(lián),Hibernate 推薦使用雙向關(guān)聯(lián),而且不要讓 1 的一端控制關(guān)聯(lián)關(guān)系,而是使用 N 的一端控制關(guān)聯(lián)關(guān)系。 雙向 1-N 與 N-1 是完全相同的兩種情形10n雙向 1-N 1 的一端需要使用集合屬性元素來映射關(guān)聯(lián)關(guān)系。集合屬性元素同樣需要增加 key 元素,還需要使用 one-to-many 元素來映射關(guān)聯(lián)屬性雙向 1-N N 的一端需要增加 many-to-one 元素來映射關(guān)聯(lián)屬
32、性。 注意:在上面的配置文件中,兩個持久化類的配置文件都需要指定外鍵列的列名,此時不可注意:在上面的配置文件中,兩個持久化類的配置文件都需要指定外鍵列的列名,此時不可以省略。因為不使用連接表的以省略。因為不使用連接表的1-N1-N關(guān)聯(lián)的外鍵,而外鍵只保存在關(guān)聯(lián)的外鍵,而外鍵只保存在N N一端的表中,如果兩邊指定一端的表中,如果兩邊指定的外鍵列名不同,將導(dǎo)致關(guān)聯(lián)映射出錯。如果不指定外鍵列的列名,該列名由系統(tǒng)自動生成,的外鍵列名不同,將導(dǎo)致關(guān)聯(lián)映射出錯。如果不指定外鍵列的列名,該列名由系統(tǒng)自動生成,而系統(tǒng)很難保存自動生成的兩個列名相同。而系統(tǒng)很難保存自動生成的兩個列名相同。雙向 1-N 測試程序1
33、:雙向 1-N 生成的表及插入的數(shù)據(jù): customers_table orders_table雙向 1-N 測試程序1產(chǎn)生的 sql 語句: 僅僅save(customer),并沒有save(order)但卻執(zhí)行了三條SQL,由生成的SQL語句可以知道,將用戶 TongGang 添加到Customers表中的同時也將 order1及order2添加到Orders表中!這是因為在 Customers.hbm.xml 映射配置中,set節(jié)點(diǎn)的設(shè)置了cascade=save-updatecascade=save-update,所以當(dāng)保存或更新Customers的時候也會自動保存相應(yīng)的Orders對
34、象!雙向 1-N 注釋掉測試程序 1 中的訂單關(guān)聯(lián)用戶的代碼: 生成同樣的 sql 語句,同樣的數(shù)據(jù)表 customers_table 中插入的數(shù)據(jù) orders_table中插入的數(shù)據(jù) 在Customers.hbm.xml的set節(jié)點(diǎn)中加了屬性 inverse=trueinverse=true,這句話的意思是將主控制權(quán)交出去:交給了Orders,也就是用戶與訂單之間從屬關(guān)系主要是由Orders對象來確定,也即訂單自己來決定它屬于哪個對象。所以在這里,將訂單關(guān)聯(lián)用戶的代碼注釋掉后,雖然后面用戶關(guān)聯(lián)了訂單,但因為用戶已經(jīng)將主動權(quán)交出,所以Hibernate在save訂單的時候并不知道訂單是屬于哪
35、個用戶,自然Customers_ID字段填空值。雙向 1-N 將Customers.hbm.xml中的 inverse=true 去掉 生成的 sql 語句: 數(shù)據(jù)庫表及插入的數(shù)據(jù)跟第一種情況相同 原來這種情況,Hibernate是先將訂單持久化到表中,因為注釋了訂單關(guān)聯(lián)用戶的代碼,所以Hibernate還是先插入空值,然后再根據(jù)用戶關(guān)聯(lián)訂單來更新Orders表將 Customers_ID字段修改為正確的值!當(dāng)數(shù)據(jù)量很大的時候,這樣的操作會影響性能,同時不能將customers_ID字段定義為not null。雙向 1-N 將inverse=true加上,而用戶關(guān)聯(lián)訂單的注釋掉 生成的 sql
36、 語句: 運(yùn)行結(jié)果是僅僅將 用戶添加到表中去了.關(guān)聯(lián)是僅僅減緩到訂單屬于哪個用戶,也就是關(guān)聯(lián)訂單的 customers_ID 字段!但用戶類里,屬性 Set orders = new HashSet();初始是為空的,這樣雖然訂單關(guān)聯(lián)了用戶,但用戶對象內(nèi)的orders屬性還是為空,訂單并沒有產(chǎn)生,這樣Hibernate在保存用戶的時候,判斷集合為空,不會去添加訂單. inverse 只有集合標(biāo)記集合標(biāo)記(set/map/list/array/bag)才有inverse屬性 在 Hibernate 中,inverse 指定了關(guān)聯(lián)關(guān)系的方向。關(guān)聯(lián) 關(guān)系中 inverse = false 的為主動方
37、,由主動方負(fù)責(zé)維護(hù) 關(guān)聯(lián)關(guān)系 在沒有設(shè)置 inverse=true 的情況下,父子兩邊都維護(hù)父子 關(guān)系 在 1-N 關(guān)系中,將 many 方設(shè)為主控方(inverse = false) 將有助于性能改善(如果要國家元首記住全國人民的名字,不 是太可能,但要讓全國人民知道國家元首,就容易的多) 在 1-N 關(guān)系中,若將 1 方設(shè)為主控方 會額外多出 update 語句。 插入數(shù)據(jù)時無法同時插入外鍵列,因而無法為外鍵列添加非空約束cascade 只有關(guān)系標(biāo)記關(guān)系標(biāo)記才有cascade屬性:many-to-one,one-to-one ,set(map, bag, idbag, list, arra
38、y) + one-to-many(many-to-many) 級聯(lián)指的是當(dāng)主控方執(zhí)行操作時,關(guān)聯(lián)對象(被動方)是否 同步執(zhí)行同一操作。 pojo和它的關(guān)系屬性的關(guān)系就是“主控方 - 被動方”的關(guān) 系,如果關(guān)系屬性是一個set,那么被動方就是set中的每一 個元素。 一個操作因級聯(lián)cascade可能觸發(fā)多個關(guān)聯(lián)操作。前一個操作 叫“主控操作”,后一個操作叫“關(guān)聯(lián)操作”。 inverse 指的是關(guān)聯(lián)關(guān)系的控制方向,而cascade指的是層級之間的連鎖操作。 cascade cascade屬性的可選值: all : 所有情況下均進(jìn)行關(guān)聯(lián)操作。 none:所有情況下均不進(jìn)行關(guān)聯(lián)操作。這是默認(rèn)值。 sa
39、ve-update:在執(zhí)行save/update/saveOrUpdate時進(jìn)行關(guān)聯(lián)操作。 delete:在執(zhí)行delete時進(jìn)行關(guān)聯(lián)操作 delete-orphan:表示刪除孤兒,delete-orphan在前者的基礎(chǔ)上增加了一點(diǎn),針對持久化對象,如果它和它所關(guān)聯(lián)的對象的引用關(guān)系不存在了,則進(jìn)行級聯(lián)刪除。 all-delete-orphan:包含all和delete-orphan的行為雙向N-N關(guān)聯(lián) 雙向N-N關(guān)聯(lián)需要兩端都使用集合屬性,兩端都增加對集合屬性的訪問。雙向N-N關(guān)聯(lián)也必須使用連接表 0n0n雙向N-N關(guān)聯(lián)雙向N-N的關(guān)聯(lián)映射需要在兩邊增加集合元素,用于映射集合屬性。集合屬性應(yīng)增
40、加key子元素用以映射外鍵列,集合元素里還應(yīng)增加many-to-many子元素關(guān)聯(lián)實(shí)體類 注意:在雙向注意:在雙向N-NN-N關(guān)聯(lián)的兩關(guān)聯(lián)的兩邊都需定連接表的表名及邊都需定連接表的表名及外鍵列的列名。兩個集合外鍵列的列名。兩個集合元素元素setset的的tabletable元素的值元素的值必須指定,而且必須相同。必須指定,而且必須相同。setset元素的兩個子元素:元素的兩個子元素:keykey和和many-to-manymany-to-many都必須都必須指定指定columncolumn屬性,其中,屬性,其中,keykey和和many-to-manymany-to-many分別指分別指定本持
41、久化類和關(guān)聯(lián)類在定本持久化類和關(guān)聯(lián)類在連接表中的外鍵列名,因連接表中的外鍵列名,因此兩邊的此兩邊的keykey與與many-to-many-to-manymany的的columncolumn屬性交叉相屬性交叉相同。也就是說,一邊的同。也就是說,一邊的setset元素的元素的keykey的的cloumncloumn值為值為a,many-to-manya,many-to-many的的columncolumn為為b b;則另一邊的;則另一邊的setset元素元素的的keykey的的columncolumn值值b,many-b,many-to-manyto-many的的columncolumn值為值為
42、a. a. 雙向1-1關(guān)聯(lián) 單向的1-1關(guān)聯(lián)有三種映射策略:基于主鍵,基于外鍵和使用連接表。雙向的1-1關(guān)聯(lián)同樣有這三種映射策略。 雙向的1-1關(guān)聯(lián)需要修改POJO類,讓兩邊都增加對關(guān)聯(lián)類的訪問基于外鍵的雙向1-1關(guān)聯(lián) 對于基于外鍵的1-1關(guān)聯(lián),其外鍵可以存放在任意一邊,在需要存放外鍵一端,增加many-to-one元素。為many-to-one元素增加unique=“true” 屬性來表示為1-1關(guān)聯(lián),并用name屬性來指定關(guān)聯(lián)屬性的屬性名。 另一端需要使用one-to-one元素,則該元素使用name屬性指定關(guān)聯(lián)的屬性名。為了讓系統(tǒng)懂得不再為本表增加一列,因此使用外鍵關(guān)聯(lián),用propert
43、y-ref屬性來引用關(guān)聯(lián)類的主鍵。 property-ref:指定目標(biāo)實(shí)體的表中外鍵引用的列。如果引用表的外鍵不引用關(guān)系的”多”端的主鍵,可以使用p該屬性指定它應(yīng)用的列。這應(yīng)該只用于已有數(shù)據(jù)庫的數(shù)據(jù)庫設(shè)計 - 在創(chuàng)建新的數(shù)據(jù)庫模式時,外鍵總是應(yīng)該引用相關(guān)表的主鍵 基于外鍵的雙向1-1關(guān)聯(lián)基于外鍵的雙向1-1關(guān)聯(lián) 生成的表 person_table address_table基于主鍵的雙向1-1關(guān)聯(lián) 基于主鍵的映射策略:指一端的主鍵生成器使用foreign略, 表明根據(jù)對方的主鍵來生成自己的主鍵,自己并不能獨(dú)立生 成主鍵。 任意一邊都可以采用foreign主鍵生成器,表明根據(jù)對方主鍵 生成自己的
44、主鍵。 采用foreign主鍵生成器策略的一端增加one-to-one元素映射 關(guān)聯(lián)屬性,其one-to-one屬性還應(yīng)增加constrained=“true”屬 性;另一端增加one-to-one元素映射關(guān)聯(lián)屬性。 constrained(約束) :表明該類對應(yīng)的表對應(yīng)的數(shù)據(jù)庫表,和被關(guān)聯(lián)的對象所對應(yīng)的數(shù)據(jù)庫表之間,通過一個外鍵引用對主鍵進(jìn)行約束?;谥麈I的雙向1-1關(guān)聯(lián)基于主鍵的雙向1-1關(guān)聯(lián) 生成的表 person_table address_table繼承映射 對于面向?qū)ο蟮某绦蛟O(shè)計語言而言,繼承和多態(tài)是兩個最基本的概念。Hibernate 的繼承映射可以理解持久化類之間的繼承關(guān)系。例
45、如:人和學(xué)生之間的關(guān)系。學(xué)生繼承了人,可以認(rèn)為學(xué)生是一個特殊的人,如果對人進(jìn)行查詢,學(xué)生的實(shí)例也將被得到。繼承映射 Hibernate支持三種繼承映射策略: 每個具體類一張表(table per concrete class) 將域模型中的每一個實(shí)體對象映射到一個獨(dú)立的表中,也就是說不用在關(guān)系開數(shù)據(jù)模型中考慮域模型中的繼承關(guān)系和多態(tài)。 每個類分層結(jié)構(gòu)一張表(table per class hierarchy) 對于繼承關(guān)系中的子類使用同一個表,這就需要在數(shù)據(jù)庫表中增加額外的區(qū)分子類類型的字段。 每個子類一張表(table per subclass) 域模型中的每個類映射到一個表,通過關(guān)系數(shù)據(jù)模
46、型中的外鍵來描述表之間的繼承關(guān)系。這也就相當(dāng)于按照域模型的結(jié)構(gòu)來建立數(shù)據(jù)庫中的表,并通過外鍵來建立表之間的繼承關(guān)系。采用 subclass 元素的繼承映射 采用 subclass 元素的繼承映射可以實(shí)現(xiàn)對于繼承關(guān)系中的子類使用同一個表 在這種映射策略下,整個繼承樹的所有實(shí)例都保保存在同一個表內(nèi)。因為父類和子類的實(shí)例全部保存在同一個表中,因此需要在該表內(nèi)增加一列,使用該列來區(qū)分每行記錄到低是哪個類的實(shí)例-這個列被稱為辨別者列(discriminator). 在這種映射策略下,使用 subclass 來映射子類,使用 discriminator-value 指定辨別者列的值采用 subclass
47、元素的繼承映射采用 subclass 元素的繼承映射 生成的表及插入的數(shù)據(jù) person_table注:所有子類定義的字段都不能有非空約束。如果為那些字段添加非空約束,那么注:所有子類定義的字段都不能有非空約束。如果為那些字段添加非空約束,那么父類的實(shí)例在那些列根本沒有值,這將引起數(shù)據(jù)庫完整性沖突,導(dǎo)致父類的實(shí)例無父類的實(shí)例在那些列根本沒有值,這將引起數(shù)據(jù)庫完整性沖突,導(dǎo)致父類的實(shí)例無法保存到數(shù)據(jù)庫中法保存到數(shù)據(jù)庫中采用 joined-subclass 元素的繼承映射 采用 joined-subclass 元素的繼承映射可以實(shí)現(xiàn)每個子類一張表 采用這種映射策略時,父類實(shí)例保存在父類表中,子類實(shí)
48、例由父類表和子類表共同存儲。因為子類實(shí)例也是一個特殊的父類實(shí)例,因此必然也包含了父類實(shí)例的屬性。于是將子類和父類共有的屬性保存在父類表中,子類增加的屬性,則保存在子類表中。 在這種映射策略下,無須使用鑒別者列,但需要為每個子類使用 key 元素映射共有主鍵,該主鍵必須與父類標(biāo)識屬性的列名相同。但如果繼承樹的深度很深,可能查詢一個子類實(shí)例時,需要跨越多個表,因為子類的數(shù)據(jù)一次保存在多個父類中。 子類增加的屬性可以添加非空約束。因為子類的屬性和父類的屬性沒有保存在同一個表中采用 joined-subclass 元素的繼承映射采用 joined-subclass 元素的繼承映射 生成的表及插入的數(shù)據(jù)
49、 person_table student_table采用 union-subclass 元素的繼承映射 采用 union-subclass 元素可以實(shí)現(xiàn)將每一個實(shí)體對象映射到一個獨(dú)立的表中。 union-subclass 與 joined-subclass 映射策略類似:子類增加的屬性也可以有非空約束 - 即父類實(shí)例的數(shù)據(jù)保存在父表中,而子類實(shí)例的數(shù)據(jù)保存在子類表中。 與 joined-subclass 不同的是,子類實(shí)例的數(shù)據(jù)僅保存在子類表中,而在父類表中沒有任何記錄。 在這種映射策略下,子類表的字段會比父類表的映射字段要多,因為子類表的字段等于父類表的字段加子類增加屬性的總和 在這種映射
50、策略下,既不需要使用鑒別者列,也無須使用 key 元素來映射共有主鍵.采用 union-subclass 元素的繼承映射采用 union-subclass 元素的繼承映射 生成的表及插入的數(shù)據(jù) person_table student_table三種繼承映射方式的比較 union-subclasssubclassjoined-subclass小結(jié) HibernateHibernate配置文件配置文件 jdbc.fetch_sizejdbc.fetch_size jdbc.batch_sizejdbc.batch_size POJO POJO 類和數(shù)據(jù)庫的映射文件類和數(shù)據(jù)庫的映射文件* *.hbm.xml.hbm.xml 主鍵生成策略主鍵生成策略generatorgenerator 映射集合屬性映射集合屬性 延遲加載策略延遲加載策略 映射組件屬性映射組件屬性 關(guān)聯(lián)關(guān)系映射:雙向關(guān)聯(lián)關(guān)系映射:雙向 1-N1-N 繼承映射繼承映射
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年防凍教育安全教育班會全文PPT
- 2025年寒假安全教育班會全文PPT
- 初中2025年冬季防溺水安全教育全文PPT
- 初中臘八節(jié)2024年專題PPT
- 主播直播培訓(xùn)提升人氣的方法正確的直播方式如何留住游客
- XX地區(qū)機(jī)關(guān)工委2024年度年終黨建工作總結(jié)述職匯報
- 心肺復(fù)蘇培訓(xùn)(心臟驟停的臨床表現(xiàn)與診斷)
- 我的大學(xué)生活介紹
- XX單位2024年終專題組織生活會理論學(xué)習(xí)理論學(xué)習(xí)強(qiáng)黨性凝心聚力建新功
- 2024年XX單位個人述職述廉報告
- 一文解讀2025中央經(jīng)濟(jì)工作會議精神(使社會信心有效提振經(jīng)濟(jì)明顯回升)
- 2025職業(yè)生涯規(guī)劃報告自我評估職業(yè)探索目標(biāo)設(shè)定發(fā)展策略
- 2024年度XX縣縣委書記個人述職報告及2025年工作計劃
- 寒假計劃中學(xué)生寒假計劃安排表(規(guī)劃好寒假的每個階段)
- 中央經(jīng)濟(jì)工作會議九大看點(diǎn)學(xué)思想強(qiáng)黨性重實(shí)踐建新功