Hibernate 5 教程_第1頁
Hibernate 5 教程_第2頁
Hibernate 5 教程_第3頁
Hibernate 5 教程_第4頁
Hibernate 5 教程_第5頁
已閱讀5頁,還剩220頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Hello Hibernate什么是 Hibernate ?n一個框架n一個 Java 領(lǐng)域的持久化持久化框架n一個 ORM 框架框架對象的持久化n 狹義的理解,“持久化”僅僅指把對象永久保存到數(shù)據(jù)庫中n 廣義的理解,“持久化”包括和數(shù)據(jù)庫相關(guān)的各種操作:保存:把對象永久保存到數(shù)據(jù)庫中。更新:更新數(shù)據(jù)庫中對象(記錄)的狀態(tài)。刪除:從數(shù)據(jù)庫中刪除一個對象。查詢:根據(jù)特定的查詢條件,把符合查詢條件的一個或多個對象從數(shù)據(jù)庫加載到內(nèi)存中。加載:根據(jù)特定的OID,把一個對象從數(shù)據(jù)庫加載到內(nèi)存中。為了在系統(tǒng)中能夠找到所需對象,需要為每一個對象分配一個唯一的標識號。為了在系統(tǒng)中能夠找到所需對象,需要為每一個

2、對象分配一個唯一的標識號。在關(guān)系數(shù)據(jù)庫中稱之為主鍵,而在對象術(shù)語中,則叫做對象標識在關(guān)系數(shù)據(jù)庫中稱之為主鍵,而在對象術(shù)語中,則叫做對象標識(Object identifier-OID). ORMn ORM(Object/Relation Mapping): 對象對象/關(guān)系關(guān)系映射映射ORM 主要解決對象-關(guān)系的映射ORM的思想:將關(guān)系數(shù)據(jù)庫中表中的記錄映射成為對象,以對象的形式展現(xiàn),程序員可以把對數(shù)據(jù)庫的操作轉(zhuǎn)化為對對象的操作程序員可以把對數(shù)據(jù)庫的操作轉(zhuǎn)化為對對象的操作。ORM 采用元數(shù)據(jù)元數(shù)據(jù)來描述對象-關(guān)系映射細節(jié), 元數(shù)據(jù)通常采用 XML 格式, 并且存放在專門的對象-關(guān)系映射文件中.O

3、RM流行的ORM框架n Hibernate:非常優(yōu)秀、成熟的 ORM 框架。完成對象的持久化操作Hibernate 允許開發(fā)者采用面向?qū)ο蟮姆绞讲捎妹嫦驅(qū)ο蟮姆绞絹聿僮麝P(guān)系數(shù)據(jù)庫。消除那些針對特定數(shù)據(jù)庫廠商的 SQL 代碼n MyBatis:相比 Hibernate 靈活高,運行速度快開發(fā)速度慢,不支持純粹的面向?qū)ο蟛僮鳎枋煜ql語 句,并且熟練使用sql語句優(yōu)化功能 n TopLinkn OJBHibernate與Jdbc代碼對比Hibernate 實現(xiàn)JDBC 實現(xiàn)Eclipse安裝 hibernate 插件n安裝方法說明:nURL:/tools/

4、Eclipse安裝 hibernate 插件n從頁面上可以看到,工具分為兩種,一種是完整版本的Eclipse插件(左),一種是只支持Jboss社區(qū)版的Eclipse插件(只有插件)(右),我們下載右邊的,它已經(jīng)足夠使用了。點擊Download:Eclipse安裝 hibernate 插件nJBoss已經(jīng)告訴我們下載插件的地址了:nURL:/jbosstools/neon/stable/updates/ Eclipse安裝 hibernate 插件n點擊Help - Install New Software.Eclipse安裝 hibernate

5、插件n點擊Add. Eclipse安裝 hibernate 插件n在Add Site對話框中, 輸入name的值為Jboss Tools,location的值為/jbosstools/neon/stable/updates/ 點擊OK按鈕Eclipse安裝 hibernate 插件n耐心等待,直到出現(xiàn)提示,選擇所有與Hibernate有關(guān)的,其余不裝。去掉Contact all update sites during install to find required software.上面的勾(一定要去掉,否則安裝會很慢),點擊nextEclip

6、se安裝 hibernate 插件Eclipse安裝 hibernate 插件n點擊accept所在的單選按鈕,接受協(xié)議,點擊nextEclipse安裝 hibernate 插件n等待安裝結(jié)束Eclipse安裝 hibernate 插件n彈出提示信息,點擊OKEclipse安裝 hibernate 插件n提示我們Eclipse需要重啟以完成安裝,點擊OKEclipse安裝 hibernate 插件n判斷安裝是否成功的標準是如果Eclipse的new選項里面有Hibernate配置文件的相關(guān)選項,就說明安裝是成功的。準備 Hibernate 環(huán)境n 導入 Hibernate 必須的 jar 包:

7、n 加入數(shù)據(jù)庫驅(qū)動的 jar 包: Hibernate開發(fā)步驟hibernate.cfg.xml *.hbm.xml2. 創(chuàng)建持久化類創(chuàng)建持久化類3. 創(chuàng)建對象創(chuàng)建對象-關(guān)系映射文關(guān)系映射文件件4. 通過通過 Hibernate API 編編寫訪問數(shù)據(jù)庫的代碼寫訪問數(shù)據(jù)庫的代碼1. 創(chuàng)建創(chuàng)建 Hibernate 配置文配置文件件1. 創(chuàng)建持久化 Java 類n 提供一個無參的構(gòu)造器提供一個無參的構(gòu)造器:使Hibernate可以使用Constructor.newInstance() 來實例化持久化類n 提供一個標識屬性提供一個標識屬性(identifier property): 通常映射為數(shù)據(jù)庫

8、表的主鍵字段. 如果沒有該屬性,一些功能將不起作用,如:Session.saveOrUpdate()n 為類的持久化類字段聲明訪問方法為類的持久化類字段聲明訪問方法(get/set): Hibernate對JavaBeans 風格的屬性實行持久化。n 使用非使用非 final 類類: 在運行時生成代理是 Hibernate 的一個重要的功能. 如果持久化類沒有實現(xiàn)任何接口, Hibnernate 使用 CGLIB 生成代理. 如果使用的是 final 類, 則無法生成 CGLIB 代理.n 重寫重寫 eqauls 和和 hashCode 方法方法: 如果需要把持久化類的實例放到 Set 中(當

9、需要進行關(guān)聯(lián)映射時), 則應該重寫這兩個方法1. 創(chuàng)建持久化 Java 類n Hibernate 不要求持久化類繼承任何父類或?qū)崿F(xiàn)接口,這可以保證代碼不被污染。這就是Hibernate被稱為低侵入式設(shè)計的原因 2. 創(chuàng)建對象-關(guān)系映射文件n Hibernate 采用 XML 格式的文件來指定對象和關(guān)系數(shù)據(jù)之間的映射. 在運行時 Hibernate 將根據(jù)這個映射文件來生成各種 SQL 語句n 映射文件的擴展名為 .hbm.xml指定類和表的映射指定持久化類的OID 和表的主鍵的映射映射類的屬性和表的字段指定對象標識符生成器, 負責為 OID 生成唯一標識符3. 創(chuàng)建 Hibernate 配置文

10、件n Hibernate 從其配置文件中讀取和數(shù)據(jù)庫連接的有關(guān)信息, 這個文件應該位于應用的 classpath 下.指定連接數(shù)據(jù)庫的基本屬性信息指定數(shù)據(jù)庫所使用的 SQL 方言指定程序運行時是否在控制臺輸出 SQL 語句指定程序運行時是否在數(shù)據(jù)庫自動生成數(shù)據(jù)表指定程序需要關(guān)聯(lián)的映射文件指定是否對輸出 SQL 語句進行格式化4. 通過Hibernate API編寫訪問數(shù)據(jù)庫的代碼n 測試代碼(Hibernate 5.2.5)/1. 創(chuàng)建一個 SessionFactory 對象StandardServiceRegistry standardRegistry = new StandardServi

11、ceRegistryBuilder() .configure(hibernate.cfg.xml).build();Metadata metadata = new MetadataSources(standardRegistry) .getMetadataBuilder().build();SessionFactoryBuilder sessionFactoryBuilder = metadata.getSessionFactoryBuilder();SessionFactory sessionFactory = sessionFactoryBuilder.build();/2. 創(chuàng)建一個 S

12、ession 對象Session session = sessionFactory.openSession();/3. 開啟事務Transaction transaction = session.beginTransaction();/4. 執(zhí)行保存操作News news = new News(Java12345, ATGUIGU, new Date(new java.util.Date().getTime();session.save(news);/5. 提交事務 mit();/6. 關(guān)閉 Sessionsession.close();/7. 關(guān)閉 SessionFactory 對象sess

13、ionFactory.close();4. 通過Hibernate API編寫訪問數(shù)據(jù)庫的代碼n 運行效果:控制臺打印輸出SQL語句4. 通過Hibernate API編寫訪問數(shù)據(jù)庫的代碼n 運行效果:數(shù)據(jù)庫增加一張表,表中插入一條字段Helloworldn 使用 Hibernate 進行數(shù)據(jù)持久化操作,通常有如下步驟:編寫持久化類: POJO + 映射文件獲取 Configuration 對象獲取 SessionFactory 對象獲取 Session,打開事務用面向?qū)ο蟮姆绞讲僮鲾?shù)據(jù)庫關(guān)閉事務,關(guān)閉 SessionConfiguration 類n Configuration 類負責管理 H

14、ibernate 的配置信息。包括如下內(nèi)容:Hibernate 運行的底層信息:數(shù)據(jù)庫的URL、用戶名、密碼、JDBC驅(qū)動類,數(shù)據(jù)庫Dialect,數(shù)據(jù)庫連接池等(對應 hibernate.cfg.xml 文件)。持久化類與數(shù)據(jù)表的映射關(guān)系(*.hbm.xml 文件)n 創(chuàng)建 Configuration 的兩種方式屬性文件(perties):Configuration cfg = new Configuration();Xml文件(hibernate.cfg.xml)Configuration cfg = new Configuration().configure()

15、;Configuration 的 configure 方法還支持帶參數(shù)的訪問:File file = new File(“simpleit.xml”);Configuration cfg = new Configuration().configure(file); SessionFactory 接口n 針對單個數(shù)據(jù)庫映射關(guān)系經(jīng)過編譯后的內(nèi)存鏡像,是線程安全的。 n SessionFactory 對象一旦構(gòu)造完畢,即被賦予特定的配置信息n SessionFactory是生成Session的工廠n 構(gòu)造 SessionFactory 很消耗資源,一般情況下一個應用中只初始化一個 SessionFa

16、ctory 對象。n Hibernate5 使用StandardServiceRegistry來獲取SessionFactoryn Hibernate5 中創(chuàng)建 SessionFactory 的步驟Session 接口n Session 是應用程序與數(shù)據(jù)庫之間交互操作的一個單線程對象單線程對象,是 Hibernate 運作的中心,所有持久化對象必須在 session 的管理下才可以進行持久化操作。此對象的生命周期很短。Session 對象有一個一級緩存,顯式執(zhí)行 flush 之前,所有的持久層操作的數(shù)據(jù)都緩存在 session 對象處。相當于相當于 JDBC 中的中的 Connection。S

17、ession 接口n 持久化類與 Session 關(guān)聯(lián)起來后就具有了持久化的能力。n Session 類的方法:取得持久化對象的方法: get() load()持久化對象都得保存,更新和刪除:save(),update(),saveOrUpdate(),delete()開啟事務: beginTransaction().管理 Session 的方法:isOpen(),flush(), clear(), evict(), close()等Transaction(事務)n 代表一次原子操作,它具有數(shù)據(jù)庫事務的概念。所有持久層都應該在事務管理下進行,即使是只讀操作。 Transaction tx =

18、session.beginTransaction();n 常用方法:commit():提交相關(guān)聯(lián)的session實例rollback():撤銷事務操作wasCommitted():檢查事務是否提交Hibernate 配置文件的兩個配置項n hbm2ddl.auto:該屬性可幫助程序員實現(xiàn)正向工程, 即由 java 代碼生成數(shù)據(jù)庫腳本, 進而生成具體的表結(jié)構(gòu). 。取值 create | update | create-drop | validatecreate : 會根據(jù) .hbm.xml 文件來生成數(shù)據(jù)表, 但是每次運行都會刪除上一次的表 ,重新生成表, 哪怕二次沒有任何改變 create-d

19、rop : 會根據(jù) .hbm.xml 文件生成表,但是SessionFactory一關(guān)閉, 表就自動刪除 update : 最常用的屬性值最常用的屬性值,也會根據(jù) .hbm.xml 文件生成表, 但若 .hbm.xml 文件和數(shù)據(jù)庫中對應的數(shù)據(jù)表的表結(jié)構(gòu)不同, Hiberante 將更新數(shù)據(jù)表結(jié)構(gòu),但不會刪除已有的行和列 validate : 會和數(shù)據(jù)庫中的表進行比較, 若 .hbm.xml 文件中的列在數(shù)據(jù)表中不存在,則拋出異常format_sql:是否將 SQL 轉(zhuǎn)化為格式良好的 SQL . 取值 true | false通過 Session 操縱對象Session 概述n Session

20、 接口是 Hibernate 向應用程序提供的操縱數(shù)據(jù)庫的最主要的接口, 它提供了基本的保存提供了基本的保存, 更新更新, 刪除和刪除和加載加載 Java 對象的方法對象的方法.n Session 具有一個緩存具有一個緩存, 位于緩存中的對象稱為持久化對象位于緩存中的對象稱為持久化對象, 它和數(shù)據(jù)庫中的相關(guān)記錄對應它和數(shù)據(jù)庫中的相關(guān)記錄對應. Session 能夠在某些時間點, 按照緩存中對象的變化來執(zhí)行相關(guān)的 SQL 語句, 來同步更新數(shù)據(jù)庫, 這一過程被稱為刷新緩存(flush)n 站在持久化的角度站在持久化的角度, Hibernate 把對象分為把對象分為 4 種狀態(tài)種狀態(tài): 持久化狀態(tài)

21、, 臨時狀態(tài), 游離狀態(tài), 刪除狀態(tài). Session 的特定方法能使對象從一個狀態(tài)轉(zhuǎn)換到另一個狀態(tài). Session 緩存n 在 Session 接口的實現(xiàn)中包含一系列的 Java 集合, 這些 Java 集合構(gòu)成了 Session 緩存. 只要 Session 實例沒有結(jié)束生命周期, 且沒有清理緩存,則存放在它緩存中的對象也不會結(jié)束生命周期n Session 緩存可減少 Hibernate 應用程序訪問數(shù)據(jù)庫的頻率。會向數(shù)據(jù)庫發(fā)送幾條 SQL ?News 對象引用變量 news引用變量 new2Session 緩存操作 Session 緩存Session 緩存數(shù)據(jù)庫News 對象news

22、記錄flush()News 對象Session 緩存Session 緩存clear()reflesh()flush 緩存n flush:Session 按照緩存中對象的屬性變化來同步更新數(shù)據(jù)庫n 默認情況下 Session 在以下時間點刷新緩存:顯式調(diào)用 Session 的的 flush() 方法當應用程序調(diào)用 Transaction 的的 commit()()方法的時, 該方法先 flush ,然后在向數(shù)據(jù)庫提交事務當應用程序執(zhí)行一些查詢(HQL, Criteria)操作時,如果緩存中持久化對象的屬性已經(jīng)發(fā)生了變化,會先 flush 緩存,以保證查詢結(jié)果能夠反映持久化對象的最新狀態(tài)n flu

23、sh 緩存的例外情況: 如果對象使用 native 生成器生成 OID, 那么當調(diào)用 Session 的 save() 方法保存對象時, 會立即執(zhí)行向數(shù)據(jù)庫插入該實體的 insert 語句.n commit() 和 flush() 方法的區(qū)別:flush 執(zhí)行一系列 sql 語句,但不提交事務;commit 方法先調(diào)用flush() 方法,然后提交事務. 意味著提交事務意味著對數(shù)據(jù)庫操作永久保存下來。Hibernate 主鍵生成策略設(shè)定刷新緩存的時間點n 若希望改變 flush 的默認時間點, 可以通過 Session 的 setFlushMode() 方法顯式設(shè)定 flush 的時間點 數(shù)據(jù)

24、庫的隔離級別n 對于同時運行的多個事務, 當這些事務訪問數(shù)據(jù)庫中相同的數(shù)據(jù)時, 如果沒有采取必要的隔離機制, 就會導致各種并發(fā)問題:臟讀臟讀: 對于兩個事物 T1, T2, T1 讀取了已經(jīng)被 T2 更新但還沒有被提交沒有被提交的字段. 之后, 若 T2 回滾, T1讀取的內(nèi)容就是臨時且無效的.不可重復讀不可重復讀: 對于兩個事物 T1, T2, T1 讀取了一個字段, 然后 T2 更新更新了該字段. 之后, T1再次讀取同一個字段, 值就不同了.幻讀幻讀: 對于兩個事物 T1, T2, T1 從一個表中讀取了一個字段, 然后 T2 在該表中插入插入了一些新的行. 之后, 如果 T1 再次讀取

25、同一個表, 就會多出幾行.n 數(shù)據(jù)庫事務的隔離性: 數(shù)據(jù)庫系統(tǒng)必須具有隔離并發(fā)運行各個事務的能力, 使它們不會相互影響, 避免各種并發(fā)問題. n 一個事務與其他事務隔離的程度稱為隔離級別. 數(shù)據(jù)庫規(guī)定了多種事務隔離級別, 不同隔離級別對應不同的干擾程度, 隔離級別越高, 數(shù)據(jù)一致性就越好, 但并發(fā)性越弱數(shù)據(jù)庫的隔離級別n 數(shù)據(jù)庫提供的 4 種事務隔離級別:n Oracle 支持的 2 種事務隔離級別:READ COMMITED, SERIALIZABLE. Oracle 默認的事務隔離級別為: READ COMMITED n Mysql 支持 4 種事務隔離級別. Mysql 默認的事務隔離級

26、別為: REPEATABLE READ在 MySql 中設(shè)置隔離級別n 每啟動一個 Mysql 程序, 就會獲得一個單獨的數(shù)據(jù)庫連接. 每個數(shù)據(jù)庫連接都有一個全局變量 tx_isolation, 表示當前的事務隔離級別. MySQL 默認的隔離級別為 Repeatable Readn 查看當前的隔離級別: SELECT tx_isolation;n 設(shè)置當前 MySQL 連接的隔離級別: set transaction isolation level read committed;n 設(shè)置數(shù)據(jù)庫系統(tǒng)的全局的隔離級別: set global transaction isolation level

27、 read committed;在Hibernate中設(shè)置隔離級別n JDBC 數(shù)據(jù)庫連接使用數(shù)據(jù)庫系統(tǒng)默認的隔離級別. 在 Hibernate 的配置文件中可以顯式的設(shè)置隔離級別. 每一個隔離級別都對應一個整數(shù):1. READ UNCOMMITED2. READ COMMITED4. REPEATABLE READ8. SERIALIZEABLEn Hibernate 通過為 Hibernate 映射文件指定 hibernate.connection.isolation 屬性來設(shè)置事務的隔離級別持久化對象的狀態(tài)n 站在持久化的角度站在持久化的角度, Hibernate 把對象分為把對象分為

28、4 種狀態(tài)種狀態(tài): 持久化狀態(tài), 臨時狀態(tài), 游離狀態(tài), 刪除狀態(tài). Session 的特定方法能使對象從一個狀態(tài)轉(zhuǎn)換到另一個狀態(tài). 持久化對象的狀態(tài)n 臨時對象(Transient): 在使用代理主鍵的情況下, OID 通常為通常為 null不處于不處于 Session 的緩存中的緩存中在數(shù)據(jù)庫中沒有對應的記錄在數(shù)據(jù)庫中沒有對應的記錄n 持久化對象(也叫”托管”)(Persist):OID 不為不為 null位于位于 Session 緩存中緩存中若在數(shù)據(jù)庫中已經(jīng)有和其對應的記錄, 持久化對象和數(shù)據(jù)庫中的相持久化對象和數(shù)據(jù)庫中的相關(guān)記錄對應關(guān)記錄對應Session 在在 flush 緩存時緩存

29、時, 會根據(jù)持久化對象的屬性變化會根據(jù)持久化對象的屬性變化, 來同來同步更新數(shù)據(jù)庫步更新數(shù)據(jù)庫在同一個在同一個 Session 實例的緩存中實例的緩存中, 數(shù)據(jù)庫表中的每條記錄只對應數(shù)據(jù)庫表中的每條記錄只對應唯一的持久化對象唯一的持久化對象持久化對象的狀態(tài)n 刪除對象(Removed)在數(shù)據(jù)庫中沒有和其 OID 對應的記錄不再處于 Session 緩存中一般情況下, 應用程序不該再使用被刪除的對象n 游離對象(也叫”脫管”) (Detached):OID 不為不為 null不再處于不再處于 Session 緩存中緩存中一般情況需下, 游離對象是由持久化對象轉(zhuǎn)變過來的, 因此在數(shù)據(jù)庫中可能還存在

30、與它對應的記錄對象的狀態(tài)轉(zhuǎn)換圖臨時狀態(tài)持久化狀態(tài)游離狀態(tài)刪除狀態(tài)new 語句get()Load()Query.list()Query.uniqueResult()Query.iterator()Query.scoll()save()saveOrUpdate()persist()merge()evict()close()clear()update()saveOrUpdate()merge()delete()delete()垃圾回收垃圾回收垃圾回收1. 是否在 Session 緩存中2. 在數(shù)據(jù)表中是否有對應的記錄Session 的 save() 方法n Session的save()方法使一個臨時

31、對象轉(zhuǎn)變?yōu)槌志没瘜ο髇 Session的save() 方法完成以下操作:把把News對象加入到對象加入到 Session 緩存中緩存中, 使它進入持久化狀態(tài)使它進入持久化狀態(tài)選用映射文件指定的標識符生成器選用映射文件指定的標識符生成器, 為持久化對象分配唯一的為持久化對象分配唯一的 OID. 在使用代理主鍵的情況下, setId()方法為對象設(shè)置OID是無效的.執(zhí)行save()方法之前,修改對象id的操作是無效的。計劃執(zhí)行一條計劃執(zhí)行一條insert語句:在語句:在flush緩存的時候緩存的時候n Hibernate通過持久化對象的OID來維持它和數(shù)據(jù)庫相關(guān)記錄的對應關(guān)系. 當News對象處于

32、持久化狀態(tài)時,不允許程序不允許程序隨意修改它的隨意修改它的IDn persist()和和save()區(qū)別區(qū)別:當對一個OID不為Null的對象執(zhí)行save()方法時,會把該對象以一個新的oid保存到數(shù)據(jù)庫中;但執(zhí)行persist()方法時會拋出一個異常.Session 的 save() 方法Session的get()和load()方法n 都可以根據(jù)跟定的 OID 從數(shù)據(jù)庫中加載一個持久化對象n 區(qū)別:當數(shù)據(jù)庫中不存在與 OID 對應的記錄時Session沒有關(guān)閉且同時需要使用對象時, load() 方法拋出 ObjectNotFoundException 異常, 而 get() 方法返回 nu

33、ll兩者采用不同的延遲檢索策略:延遲檢索策略:load 方法支持延遲加載方法支持延遲加載策略(返回的是代理對象)。而策略(返回的是代理對象)。而 get 不支持。不支持。load方法存在方法存在懶加載異常問題懶加載異常問題:由于:由于load使用的是延遲加使用的是延遲加載策略,返回的是代理對象。在使用對象之前提前關(guān)閉了載策略,返回的是代理對象。在使用對象之前提前關(guān)閉了session會發(fā)生懶加載異常。會發(fā)生懶加載異常。get方法不存在這個問題。方法不存在這個問題。Session的get()和load()方法load()方法:懶加載異常發(fā)生異常的原因:在發(fā)生異常的原因:在需要需要初始化代初始化代理

34、理對象之前已經(jīng)關(guān)閉了對象之前已經(jīng)關(guān)閉了 Sessionload方法返回的是代理對象方法返回的是代理對象Session 的 update() 方法n Session 的 update() 方法使一個游離對象轉(zhuǎn)變?yōu)槌志没瘜ο? 并且計劃執(zhí)行一條 update 語句.n 若希望 Session 僅當修改了 News 對象的屬性時, 才執(zhí)行 update() 語句, 可以把映射文件中 元素的 select-before-update 設(shè)為 true. 該屬性的默認值為 falsen 當當 update() 方法關(guān)聯(lián)一個游離對象時方法關(guān)聯(lián)一個游離對象時, 如果在如果在 Session 的緩存中已經(jīng)存在相

35、同的緩存中已經(jīng)存在相同 OID 的持久化對象的持久化對象, 會拋出異常會拋出異常n 當 update() 方法關(guān)聯(lián)一個游離對象時, 如果在數(shù)據(jù)庫中不存在相應的記錄, 也會拋出異常. Session 的 update() 方法 需要注意的:1. 無論要更新的游離對象和數(shù)據(jù)表的記錄是否一致, 都會發(fā)送 UPDATE 語句.(如果為更新操作設(shè)置了觸發(fā)器則盲目發(fā)送的update語句會使得觸發(fā)器被錯誤的執(zhí)行多次) 如果想讓 update 方法不再盲目的出發(fā) update 語句,需要在 .hbm.xml 文件的 class 節(jié)點設(shè)置select-before-update=true (默認為 false)

36、. 但通常不需要設(shè)置該屬性. 2. 若數(shù)據(jù)表中沒有對應的記錄, 但還調(diào)用了 update 方法, 會拋出異常3. 當 update() 方法關(guān)聯(lián)一個游離對象時, 如果在 Session 的緩存中已經(jīng)存在相同 OID 的持久化對象, 會拋出異常. 因為在在 Session 緩存緩存中不能中不能有兩個有兩個 OID 相同的對象相同的對象!設(shè)置select-before-update=true后的顯示效果OID不存在時執(zhí)行update()方法的異常Session 的 saveOrUpdate() 方法Session 的 saveOrUpdate() 方法n Session 的 saveOrUpdat

37、e() 方法同時包含了 save() 與 update() 方法的功能News 對象游離對象臨時對象update()save()判定對象為臨時對象的標準 Java 對象的對象的 OID 為為 null 映射文件中為 設(shè)置了 unsaved-value 屬性, 并且 Java 對象的 OID 取值與這個 unsaved-value 屬性值匹配Session 的 saveOrUpdate() 方法n 注意:1. 若 OID 不為 null, 但數(shù)據(jù)表中還沒有和其對應的記錄. 會拋出一個異常. 2. 了解: OID 值等于 id 的 unsaved-value 屬性值的對象, 也被認為是一個游離對象

38、Session 的 merge() 方法Session 的 merge() 方法news1 的狀態(tài)Session緩存中是否存在OID為1的News持久化對象數(shù)據(jù)庫中是否存在id為1的記錄從數(shù)據(jù)庫加載id為1的News持久化對象把new1對象的屬性拷貝到New持久化對象中,計劃執(zhí)行一條update語句游離對象存在不存在創(chuàng)建一個新的News對象,把new1對象的屬性拷貝到新建的News對象中,持久化這個News對象,計劃執(zhí)行一條insert語句返回News持久化對象的引用存在臨時對象不存在Session 的 delete() 方法n Session 的 delete() 方法既可以刪除一個游離對象

39、, 也可以刪除一個持久化對象n Session 的 delete() 方法處理過程計劃執(zhí)行一條 delete 語句把對象從 Session 緩存中刪除, 該對象進入刪除狀態(tài).n Hibernate 的 cfg.xml 配置文件中有一個 hibernate.use_identifier_rollback 屬性, 其默認值為 false, 若把它設(shè)為 true, 將改變 delete() 方法的運行行為: delete() 方法會把持久化對象或游離對象的 OID 設(shè)置為 null, 使它們變?yōu)榕R時對象Session 的 delete() 方法Session 的 delete() 方法n若OID在數(shù)

40、據(jù)表中沒有記錄則拋出異常Session 的 evict() 方法n從 session 緩存中把指定的持久化對象移除,對象從持久化狀態(tài)變?yōu)槊摴軤顟B(tài)。通過 Hibernate 調(diào)用存儲過程n Work 接口: 直接通過 JDBC API 來訪問數(shù)據(jù)庫的操作通過 Hibernate 調(diào)用存儲過程n Session 的 doWork(Work) 方法用于執(zhí)行 Work 對象指定的操作, 即調(diào)用 Work 對象的 execute() 方法. Session 會把當前使用的數(shù)據(jù)庫連接傳遞給 execute() 方法.Hibernate 與觸發(fā)器協(xié)同工作n Hibernate 與數(shù)據(jù)庫中的觸發(fā)器協(xié)同工作時,

41、 會造成兩類問題觸發(fā)器使Session的緩存中的持久化對象與數(shù)據(jù)庫中對應的數(shù)據(jù)不一致:觸發(fā)器運行在數(shù)據(jù)庫中,它執(zhí)行的操作對Session是透明的Session的update()方法盲目地激發(fā)觸發(fā)器: 無論游離對象的屬性是否發(fā)生變化, 都會執(zhí)行update語句,而update語句會激發(fā)數(shù)據(jù)庫中相應的觸發(fā)器n 解決方案: 在執(zhí)行完Session的相關(guān)操作后, 立即調(diào)用Session的flush()和refresh() 方法, 迫使Session 的緩存與數(shù)據(jù)庫同步(refresh() 方法重新從數(shù)據(jù)庫中加載對象)在映射文件的的 元素中設(shè)置 select-before-update 屬性: 當 Se

42、ssion 的 update 或 saveOrUpdate() 方法更新一個游離對象時, 會先執(zhí)行 Select 語句, 獲得當前游離對象在數(shù)據(jù)庫中的最新數(shù)據(jù), 只有在不一致的情況下才會執(zhí)行 update 語句內(nèi)存數(shù)據(jù)庫News 對象news 記錄flush()reflesh()Hibernate 的配置文件Hibernate配置文件概述 n Hibernate 配置文件主要用于配置數(shù)據(jù)庫連接和 Hibernate 運行時所需的各種屬性n 每個 Hibernate 配置文件對應一個 Configuration 對象n Hibernate配置文件可以有兩種格式:pert

43、ieshibernate.cfg.xml JDBC 連接屬性nJDBC 連接屬性connection.url:數(shù)據(jù)庫URL connection.username:數(shù)據(jù)庫用戶名connection.password:數(shù)據(jù)庫用戶密碼 connection.driver_class:數(shù)據(jù)庫JDBC驅(qū)動 dialect:配置數(shù)據(jù)庫的方言,根據(jù)底層的數(shù)據(jù)庫不同產(chǎn)生不同的 sql 語句,Hibernate 會針對數(shù)據(jù)庫的特性在訪問時進行優(yōu)化導入C3P0 jar包n 導入C3P0 jar包n 位置:hibernate-release-5.2.5.Finalliboptionalc3p0*.jarC3P0

44、數(shù)據(jù)庫連接池屬性n C3P0 數(shù)據(jù)庫連接池屬性hibernate.c3p0.max_size: 數(shù)據(jù)庫連接池的最大連接數(shù)hibernate.c3p0.min_size: 數(shù)據(jù)庫連接池的最小連接數(shù)hibernate.c3p0.timeout: 數(shù)據(jù)庫連接池中連接對象在多長時間沒有使用過后,就應該被銷毀hibernate.c3p0.max_statements: 緩存 Statement 對象的數(shù)量hibernate.c3p0.idle_test_period: 表示連接池檢測線程檢測線程多長時間檢測一次池內(nèi)的所有鏈接對象是否超時. 連接池本身不會把自己從連接池中移除,而是專門有一個線程按照一定的

45、時間間隔來做這件事,這個線程通過比較連接對象最后一次被使用時間和當前時間的時間差來和 timeout 做對比,進而決定是否銷毀這個連接對象。 hibernate.c3p0.acquire_increment: 當數(shù)據(jù)庫連接池中的連接耗盡時, 同一時刻獲取多少個數(shù)據(jù)庫連接hibernate.cfg.xml的常用屬性n 其他show_sql:是否將運行期生成的SQL輸出到日志以供調(diào)試。取值 true | false format_sql:是否將 SQL 轉(zhuǎn)化為格式良好的 SQL . 取值 true | falsehbm2ddl.auto:在啟動和停止時自動地創(chuàng)建,更新或刪除數(shù)據(jù)庫模式。取值 cre

46、ate | update | create-drop | validatehibernate.jdbc.fetch_sizehibernate.jdbc.batch_sizejdbc.fetch_sizejdbc.fetch_size 和和 jdbc.batch_sizejdbc.batch_sizen hibernate.jdbc.fetch_size:實質(zhì)是調(diào)用 Statement.setFetchSize() 方法設(shè)定設(shè)定 JDBC JDBC 的的 Statement Statement 讀取數(shù)據(jù)的時候每次從數(shù)據(jù)庫中取出的記讀取數(shù)據(jù)的時候每次從數(shù)據(jù)庫中取出的記錄條數(shù)錄條數(shù)。例如一次查詢1

47、萬條記錄,對于Oracle的JDBC驅(qū)動來說,是不會 1 次性把1萬條取出來的,而只會取出 fetchSize 條數(shù),當結(jié)果集遍歷完了這些記錄以后,再去數(shù)據(jù)庫取 fetchSize 條數(shù)據(jù)。因此大大節(jié)省了無謂的內(nèi)存消耗。Fetch Size設(shè)的越大,讀數(shù)據(jù)庫的次數(shù)越少,速度越快;Fetch Size越小,讀數(shù)據(jù)庫的次數(shù)越多,速度越慢。Oracle數(shù)據(jù)庫的JDBC驅(qū)動默認的Fetch Size = 10,是一個保守的設(shè)定,根據(jù)測試,當Fetch Size=50時,性能會提升1倍之多,當 fetchSizeetchSize=100=100,性能還能繼續(xù)提升20%,F(xiàn)etch Size繼續(xù)增大,性能

48、提升的就不顯著了。并不是所有的數(shù)據(jù)庫都支持Fetch Size特性,例如MySQL就不支持n hibernate.jdbc.batch_size:設(shè)定對數(shù)據(jù)庫進行批量刪除,批量更新和設(shè)定對數(shù)據(jù)庫進行批量刪除,批量更新和批量插入的時候的批次大小批量插入的時候的批次大小,類似于設(shè)置緩沖區(qū)大小的意思。batchSize 越大,批量操作時向數(shù)據(jù)庫發(fā)送sql的次數(shù)越少,速度就越快。測試結(jié)果是當Batch Size=0的時候,使用Hibernate對Oracle數(shù)據(jù)庫刪除1萬條記錄需要25秒,Batch Size = 50的時候,刪除僅僅需要5秒!Oracle數(shù)據(jù)庫 batchSizeatchSize=3

49、0=30 的時候比較合適。對象關(guān)系映射文件POJO 類和數(shù)據(jù)庫的映射文件*.hbm.xmln POJO 類和關(guān)系數(shù)據(jù)庫之間的映射可以用一個XML文檔來定義。n 通過 POJO 類的數(shù)據(jù)庫映射文件,Hibernate可以理解持久化類和數(shù)據(jù)表之間的對應關(guān)系,也可以理解持久化類屬性與數(shù)據(jù)庫表列之間的對應關(guān)系n 在運行時 Hibernate 將根據(jù)這個映射文件來生成各種 SQL 語句n 映射文件的擴展名為 .hbm.xmlHiberrnate-mapping映射文件說明n hibernate-mapping類層次:class主鍵:id基本類型:property實體引用類: many-to-one |

50、one-to-one集合:set | list | map | arrayone-to-manymany-to-many子類:subclass | joined-subclass其它:component | any 等查詢語句:query(用來放置查詢語句,便于對數(shù)據(jù)庫查詢的統(tǒng)一管理和優(yōu)化)n 每個Hibernate-mapping中可以同時定義多個類. 但更推薦為每個類都創(chuàng)建一個單獨的映射文件hibernate-mapping hibernate-mapping 是是 hibernate 映射文件的根映射文件的根元素元素schema: 指定所映射的數(shù)據(jù)庫指定所映射的數(shù)據(jù)庫schema的名稱。

51、若指定該屬的名稱。若指定該屬性性, 則表明會自動添加該則表明會自動添加該 schema 前綴前綴catalog:指定所映射的數(shù)據(jù)庫指定所映射的數(shù)據(jù)庫catalog的名稱。的名稱。 default-cascade(默認為默認為 none): 設(shè)置設(shè)置hibernate默認的默認的級聯(lián)風格級聯(lián)風格. 若配置若配置 Java 屬性屬性, 集合映射時沒有指定集合映射時沒有指定 cascade 屬性屬性, 則則 Hibernate 將采用此處指定的級聯(lián)風格將采用此處指定的級聯(lián)風格. default-access (默認為默認為 property): 指定指定 Hibernate 的默認的屬性訪問策略。默

52、認值為的默認的屬性訪問策略。默認值為 property, 即使用即使用 getter, setter 方法來訪問屬性方法來訪問屬性. 若指定若指定 access, 則則 Hibernate 會忽略會忽略 getter/setter 方法方法, 而通過反射訪而通過反射訪問成員變量問成員變量.default-lazy(默認為默認為 true): 設(shè)置設(shè)置 Hibernat morning的延遲加載策略的延遲加載策略. 該屬性的默認值為該屬性的默認值為 true, 即啟用延遲加即啟用延遲加載策略載策略. 若配置若配置 Java 屬性映射屬性映射, 集合映射時沒有指定集合映射時沒有指定 lazy 屬性

53、屬性, 則則 Hibernate 將采用此處指定的延遲加載策將采用此處指定的延遲加載策略略 auto-import (默認為默認為 true): 指定是否可以在查詢語言中指定是否可以在查詢語言中使用非全限定的類名(僅限于本映射文件中的類)。使用非全限定的類名(僅限于本映射文件中的類)。 package (可選可選): 指定一個包前綴,如果在映射文檔中沒有指定一個包前綴,如果在映射文檔中沒有指定全限定的類名,指定全限定的類名, 就使用這個作為包名。就使用這個作為包名。 詳細取值參看:詳細取值參看:http:/ class 元素用于指定類和表的映射元素用于指定類和表的映射name:指定該持久化類映

54、射的持久化類的類名指定該持久化類映射的持久化類的類名table:指定該持久化類映射的表名指定該持久化類映射的表名, Hibernate 默認默認以持久化類的類名作為表名以持久化類的類名作為表名dynamic-insert: 若設(shè)置為若設(shè)置為 true, 表示當保存一個表示當保存一個對象時對象時, 會動態(tài)生成會動態(tài)生成 insert 語句語句, insert 語句中語句中僅包含所有取值不為僅包含所有取值不為 null 的字段的字段. 默認值為默認值為 falsedynamic-update: 若設(shè)置為若設(shè)置為 true, 表示當更新一個表示當更新一個對象時對象時, 會動態(tài)生成會動態(tài)生成 upda

55、te 語句語句, update 語句中語句中僅包含所有取值需要更新的字段僅包含所有取值需要更新的字段. 默認值為默認值為 falseselect-before-update:設(shè)置設(shè)置 Hibernate 在更新某在更新某個持久化對象之前是否需要先執(zhí)行一次查詢個持久化對象之前是否需要先執(zhí)行一次查詢. 默認值默認值為為 falsebatch-size:指定根據(jù)指定根據(jù) OID 來抓取實例時每批抓取的來抓取實例時每批抓取的實例數(shù)實例數(shù).lazy: 指定是否使用延遲加載指定是否使用延遲加載. mutable: 若設(shè)置為若設(shè)置為 true, 等價于所有的等價于所有的 元素的元素的 update 屬性為屬

56、性為 false, 表示整表示整個實例不能被更新個實例不能被更新. 默認為默認為 true. discriminator-value: 指定區(qū)分不同子類的值指定區(qū)分不同子類的值. 當當使用使用 元素來定義持久化類的繼承關(guān)系元素來定義持久化類的繼承關(guān)系時需要使用該屬性時需要使用該屬性詳細取值參看:詳細取值參看:http:/ Hibernate 使用對象標識符(OID) 來建立內(nèi)存中的對象和數(shù)據(jù)庫表中記錄的對應關(guān)系. 對象的 OID 和數(shù)據(jù)表的主鍵對應. Hibernate 通過標識符生成器來為主鍵賦值n Hibernate 推薦在數(shù)據(jù)表中使用代理主鍵, 即不具備業(yè)務含義的字段. 代理主鍵通常為整

57、數(shù)類型, 因為整數(shù)類型比字符串類型要節(jié)省更多的數(shù)據(jù)庫空間.n 在對象-關(guān)系映射文件中, 元素用來設(shè)置對象標識符. 子元素用來設(shè)定標識符生成器.n Hibernate 提供了標識符生成器接口: IdentifierGenerator, 并提供了各種內(nèi)置實現(xiàn)id id:設(shè)定持久化類的:設(shè)定持久化類的 OID 和表的主鍵的映射和表的主鍵的映射 name: 標識持久化類標識持久化類 OID 的屬性名的屬性名 column: 設(shè)置標識屬性所映射的數(shù)據(jù)表的列名設(shè)置標識屬性所映射的數(shù)據(jù)表的列名(主鍵字段主鍵字段的名字的名字). unsaved-value:若設(shè)定了該屬性若設(shè)定了該屬性, Hibernate

58、會通過會通過比較持久化類的比較持久化類的 OID 值和該屬性值來區(qū)分當前持久化類值和該屬性值來區(qū)分當前持久化類的對象是否為臨時對象的對象是否為臨時對象 type:指定指定 Hibernate 映射類型映射類型. Hibernate 映射類映射類型是型是 Java 類型與類型與 SQL 類型的橋梁類型的橋梁. 如果沒有為某個如果沒有為某個屬性顯式設(shè)定映射類型屬性顯式設(shè)定映射類型, Hibernate 會運用反射機制先會運用反射機制先識別出持久化類的特定屬性的識別出持久化類的特定屬性的 Java 類型類型, 然后自動使然后自動使用與之對應的默認的用與之對應的默認的 Hibernate 映射類型映射

59、類型 Java 的基本數(shù)據(jù)類型和包裝類型對應相同的的基本數(shù)據(jù)類型和包裝類型對應相同的 Hibernate 映射類型映射類型. 基本數(shù)據(jù)類型無法表達基本數(shù)據(jù)類型無法表達 null, 所以對于持久化類的所以對于持久化類的 OID 推薦使用包裝類型推薦使用包裝類型saveOrUpdate詳細取值參看:詳細取值參看:http:/ generatorgenerator:設(shè)定持久化類設(shè)定標識符生成器:設(shè)定持久化類設(shè)定標識符生成器 class: class: 指定使用的標識符生成器全限定類名或其縮寫名指定使用的標識符生成器全限定類名或其縮寫名詳細取值參看:詳細取值參看:http:/ Hibernate提供的

60、內(nèi)置標識符生成器: 詳細取值參看:詳細取值參看:http:/ 標識符生成器n increment 標識符生成器由由 Hibernate 以遞增的方式為代理主鍵賦值n Hibernate 會先讀取 NEWS 表中的主鍵的最大值, 而接下來向 NEWS 表中插入記錄時, 就在 max(id) 的基礎(chǔ)上遞增, 增量為 1.n 適用范圍:由于 increment 生存標識符機制不依賴于底層數(shù)據(jù)庫系統(tǒng), 因此它適合所有的數(shù)據(jù)庫系統(tǒng)適用于只有單個 Hibernate 應用進程應用進程訪問同一個數(shù)據(jù)庫的場合, 在集群環(huán)境下不推薦使用它OID 必須為 long, int 或 short 類型, 如果把 OID

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論