1.JPA的實體生命週期:java
JPA的實體有如下4中生命週期狀態:spring
(1).New:瞬時對象,還沒有有id,還未和Persistence Context創建關聯的對象。數據庫
(2).Managed:持久化受管對象,有id值,已經和Persistence Context創建了關聯的對象。數組
(3).Datached:遊離態離線對象,有id值,但沒有和Persistence Context創建關聯的對象。緩存
(4).Removed:刪除的對象,有id值,尚且和Persistence Context有關聯,可是已經準備好從數據庫中刪除。服務器
四種狀態總結:併發
狀態名 做爲java對象存在 在實體管理器中存在 在數據庫存在分佈式
New yes no no性能
Managed yes yes yesui
Detached no no no
Removed yes yes no
2.JPA實體狀態的切換:
JPA實體的四種狀態之間能夠進行切換,具體以下:
3.容器管理和應用程序管理的EntityManager實體管理器:
在JPA中有兩種管理實體管理器的方法:
(1).容器管理(Container-Manager)的實體管理器:
容器管理實體管理器,是由JavaEE容器所管理的實體管理器,經過PersistenceContext注入方式來生成實體管理器,具體代碼以下:
@PersistenceContext(unitName=」持久化單元名稱」)
Protected EntityManagerem;
(2).應用程序管理(Application-Manager)的實體管理器:
JPA不但能夠在JavaEE容器中使用,也能夠脫離JavaEE容器在JavaSE程序中使用,當JPA脫離了JavaEE服務器環境時,就須要經過應用程序來獲取實體管理器,具體代碼以下:
a. 代碼方式:
//首先根據持久化單元建立實體管理器工廠
EntityManagerFactoryemf = Persistence.createEntityManagerFacotory(持久化策略文件中的持久化單元名稱);
//經過實體管理器工廠建立實體管理器
EntityManager em= emf.createEntityManager();
b. 註解方式:
//將持久化單元注入實體管理器工廠中
@PersistenceUnit(持久化單元名稱)
protected EntityManagerFactory emf;
protected EntityManager em = emf.createEntityManager();
注意:當持久化策略文件中只有一個持久化單元時,在註解中不用指定支持化單元名稱。
4.JPA實體管理器的經常使用方法:
(1).find查找:至關於Hibernate中的get操做,若是一級緩存查找不到會當即去數據庫查找,若是查找不到會返回null。
(2).getReference查找:至關於Hibernate中的load操做,若是一級緩存查找不到並不當即去數據庫查找,而是去查找二級緩存,返回實體對象的代理,若是查找不到會拋出ObjectNotFindException。
(3).persist:使實體類從new狀態或者removed轉變到managed狀態,並將數據保存到底層數據庫中。
(4).remove:將實體變爲removed狀態,當實體管理器關閉或者刷新時,纔會真正地刪除數據。
(5).flush:將實體和底層數據庫進行同步,當調用persist、merge或者remove方法時,更新並不會馬上同步到數據庫中,直到容器決定刷新到數據庫中時纔會執行,能夠調用flush強制刷新。
(6).createQuery:根據JPA QL定義查詢對象。
(7).createNativeQuery:容許開發人員根據特定數據庫的SQL語法來進行查詢操做,只有JPA QL不能知足要求時才使用,不推薦使用,由於增長了程序可移植性。
(8).createNamedQuery:根據實體中標註的命名查詢建立查詢對象。
(9).merge:將一個detached的實體持久化到數據庫中,並轉換爲managed狀態。
5.JPA分頁查詢:
(1).爲實體管理器建立的查詢對象設置返回最大結果數:setMaxResults(int maxResult);
(2).爲實體管理器建立的查詢對象設置返回結果開始下標:setFirstResult(int firstResult);
6.JPA中調用存儲過程:
注意:JPA中只能調用兩種存儲過程:1.無返回值的存儲過程。2.返回值爲ResultSet的存儲過程(不能是out)。
實體管理器的createNativeQuery(」{call 存儲過程名()}」);便可調用數據庫的存儲過程。
7.JPA的命名參數:
語法:「:參數名」。
例如:
Query query = entityManager.createQuery(」selectu from User u where u.name=:name」);
//設置查詢中的命名參數
Query.setParameter(「name」, testName);
注意:不容許在同一個查詢中使用兩個相同名字的命名參數。
8.JPA的位置參數:
語法:「?位置參數索引」。
例如:
Query query = entityManager.createQuery(」selectu from User u where u.name=?1」);
//設置查詢中的位置參數
Query.setParameter(1, testName);
注意:JPA中的位置參數索引值從1開始。
9.JPA的集合查詢:
咱們知道在SQL語句中,查找某元素是否在某個集合中時經常使用相似:in(a,b,c)的查詢語句,在JDBC中咱們經常須要將集合元素拼接成以逗號(「,」)分隔的字符串,在JPA中有兩種方法能夠方便地進行判斷元素是否在集合中的查詢:
(1).設置集合類型的參數:
查詢對象的setParameter方法支持Object類型,所以能夠傳入一個集合類型的參數,如數組或者ArrayList等。
例如:
Query query = em.createQuery(「select * fromUsers where name in(?names)」);
query.setParameter(「name」, names);//names是一個name集合
(2).使用member of關鍵字:
例如:
Select t from Topic t where :option memberof t.options;
10.JPA的回調方法:
JPA中,實體類支持一些回調方法,能夠經過以下的註解指定回調方法:
(1).@PrePersist:在persist方法調用後馬上發生,級聯保存也會發生該事件,此時數據尚未真實插入數據庫中。
(2).@PostPersist:數據已經插入進數據庫中後觸發。
(3).@PreRemove:在實體從數據庫刪除以前觸發。級聯刪除也會觸發該事件,此時數據尚未真實從數據庫中刪除。
(4).@PostRemove:在實體已經從數據庫中刪除後觸發。
(5).@PreUpdate:在實體的狀態同步到數據庫以前觸發,此時數據尚未真實更新到數據庫中。
(6).@PostUpdate:在實體的狀態同步到數據庫後觸發,同步在事務提交時發生。
(7).@PostLoad:在如下狀況觸發:
a.執行find或者getReference方法載入一個實體以後。
b.執行JPA QL查詢以後。
c.refresh方法被調用以後。
11.事務管理特性:
事務所數據庫的一個邏輯工做單元,包含一系列的操做,事務有四個特性,即ACID特性:
(1).Atomic(原子性):
事務中的各個操做不可分割,事務中所包含的操做被看做一個邏輯單元,這個邏輯單元中的操做要麼所有成功,要麼所有失敗。
(2).Consistency(一致性):
一致性意味着,只有合法的數據才能夠被寫入數據庫,若是數據有任何不符合,則事務應該將其回滾。
(3).Isolation(隔離性):
事務容許多個用戶對同一個數據的併發訪問,而不破壞數據的正確性和完整性。同時,並行事務的修改必須與其餘並行事務的修改相互獨立。按照比較嚴格隔離邏輯來說,一個事務看到的數據要麼是另一個事務修改這些數據以前的狀態,要麼是一個事務已經修改完成的數據,決不能是其餘事務正在修改的數據。
(4).Durability(持久性):
事務結束後,事務處理的結果必須可以獲得持久化。
12.數據操做過程當中可能會出現的3中不肯定狀況:
(1).髒讀取:
一個事務讀取了另外一個並行事務未提交的數據。
(2).不可重複讀:
一個事務再次讀取以前曾經讀過的數據時,發現該數據已經被另外一個已提交的事務修改。
(3).幻讀:
同一查詢在同一事務中屢次進行,因爲其餘事務提交所作的操做,使得每次返回不一樣的結果集,從而產生換讀。
13.事務的隔離級別:
事務的隔離,是指數據庫(或其餘事務系統)經過某種機制,在並行的多個事務之間進行分割,使得每一個事務在其執行過程當中保持獨立,如同當前只有一個事務在單獨運行。爲了不12中3中不肯定狀況的發生,標準的SQL規範中定義了以下4中事務隔離級別:
(1).爲提交讀:
最低等級的事務隔離,僅僅保證了讀取過程當中不會讀取到非法數據。
(2).已提交讀:
該級別的事務隔離保證了一個事務不會讀取到另外一個並行事務已修改但未提交的數據,避免了髒讀。大多數主流數據庫默認的事務隔離等級是已提交讀。
(3).重複讀:
該級別的事務隔離避免了髒讀和不可重複讀,可是也意味着,一個事務部可能更新已經由另外一個事務讀取但未提交的數據。
(4).序列化:
最高等級的事務隔離,也提供了最嚴格的隔離機制,上面3種不肯定狀況均可以被避免。該級別將模擬事務的串行執行,邏輯上如同全部的事務都處於一個執行隊列中,依次串行執行,而非並行執行。
4種事務隔離級別總結:
隔離等級 髒讀 不可重複讀 幻讀
未提交讀 可能 可能 可能
提交讀 不可能 可能 可能
重複讀 不可能 不可能 可能
序列化 不可能 不可能 不可能
9. JDBC事務和JTA事務:
JDBC事務:只能支持一個數據庫,單數據源,一個由數據庫自己來執行提交或回滾,單階段提交,本地事務。JDBC事務由Connection管理,事務週期侷限於Connection的生命週期以內。
JTA事務:JTA提供了跨Session的事務管理能力,支持多數據源的分佈式事務,兩階段提交。JTA事務管理由JTA容器實現,JTA容器對當前加入事務的衆多Connection進行調度,實現其事務性要求,JTA的事務週期可橫跨多個JDBC Connection生命週期。
10. 事務的傳播特性:
事務傳播特性是用於指定當進行操做時,如何使用事務,JPA中有如下6種事務傳播特性:
(1).Not Support:不支持,若當前事務有上下文,則掛起。
(2).Support:支持,如有事務,則使用事務,若無事務,則不使用事務。
(3).Required:須要,如有事務,則使用使用,若無事務,則建立新的事務。
(4).Required New:須要新事務,每次都會建立新的事務。
(5).Mandatory:必須有事務,若無事務,則將拋出異常。
(6).Never:必須不能有事務,如有事務,則會拋出異常。
16.鎖的機制:
所謂鎖,就是給選定的目標對象加上限制,使其沒法被其餘程序所修改,JPA支持兩種鎖機制:樂觀鎖和悲觀鎖。
(1).悲觀鎖:
對數據被外界修改持保守態度,在整個數據處理過程當中,將數據處於鎖定狀態,悲觀鎖的實現,每每依靠數據庫提供的鎖機制。最經常使用的悲觀鎖是在查詢時加上「for update「,用法以下:
Select * from user where name=」test」 forupdate
在JPA中,能夠經過給Query對象設置鎖模式(query.setLockMode)來制定悲觀鎖的模式:
a.LockMode.NONE:無鎖機制。
b.LockMode.WRITE:在insert和update時會自動加鎖。
c.LockMode.READ:在讀取記錄時會自動加鎖。
d.LockMode.UPGRADE:利用數據庫的for update字句加鎖。
(2).樂觀鎖:
相對於悲觀鎖,樂觀鎖機制採用較爲寬鬆的加鎖機制,悲觀鎖大多數狀況下依靠數據庫鎖的機制實現,以保證操做最大程度的獨佔性,可是數據庫的性能開銷比較大。而樂觀鎖大多數基於數據版本(version)記錄或者時間戳機制實現。
基於版本的樂觀鎖在讀取數據時將數據的版本號一同讀出,以後更新則對版本號加1,提交時對數據的版本與數據庫中對應的版本進行比較,若是提交數據數據版本號打於數據庫中當前版本號,則予以更新,不然認爲是過時數據。樂觀鎖大大減少了數據庫開銷,提升了程序的性能。
JPA中能夠在實體中使用@Version註解指定其使用樂觀鎖,JPA會在數據庫對應的表中自動生成和維護一列版本號。
17.Spring集成JPA:
JPA不但能夠在JavaEE環境中使用,也能夠還JavaSE環境中使用,spring如今在java開發中應用很是普遍,Spring一樣提供了對JPA的強大支持。Spring集成JPA的步驟以下:
(1).在MATE-INF下添加JPA的持久化策略文件,開發實體bean。
(2).爲工程引入Spring支持。添加Spring相關依賴包和spring配置文件。
(3).在spring配置文件中加入JPA配置以下:
<bean id=」entityManagerFactory」
class=」org.springframework.orm.jpa.LocalEntityManagerFactoryBean」>
<propertyname=」persistenceUnitName」 value=」持久化單元名稱」/>
</bean>
<bean id=」transactionManager」
class=」org.springframework.orm.jpa.JpaTransactionManager」>
<propertyname=」entityManagerFactory」 ref=」 entityManagerFactory」/>
</bean>
<tx:annotation-driventransaction-manager=」 transactionManager」/>
至此,Spring和JPA的簡單集成完成。