JPA规范的主要内容
?來源:http://www.cnblogs.com/RicCC/archive/2009/01/06/jpa-java-persistence-api.html
?
Entity Identity 實體標識
一般采用單一值做為entity identity
采用compsite primary key時,必須單獨建立一個表示主鍵的類-primary key class主鍵類。這樣在實體上compsite primary key就可以用一個屬性(primary key class類型)表示
持久化框架內部很多地方使用entity identity進行處理,因此primary key class要正確實現equals、hashCode方法
另外應用層需要注意,對persistence context中受管理的對象,不要修改主鍵值,否則持久化框架無法承諾帶來的影響,因為persistence context只能基于entity identity標識實體身份
Accessor of Persistent Fields and Properties 持久化值域和屬性的訪問器
Persistent state(即需要持久化的fields或properties)的存取分2種類型:field-based和property-based
field-based時持久化框架直接存取instance variables,property-based時則通過getter、setter方法存取
使用property-based時,在setter、getter方法中可能包含業務邏輯,對于應用層而言,需要注意的是持久化框架從數據庫加載數據,為實體屬性賦值時,各屬性的賦值順序是無法承諾的,因此getter、setter中的業務邏輯需要注意這一點
另外使用property-based時如果還將屬性聲明為lazy-fetching,則應用層不應當訪問相應的instance variable,因為持久化框架可能對setter、getter進行注入以實現lazy-fetching,直接訪問instance variable可能獲取不到值
對于集合類型,JPA規定必須使用java.util下面的Collection、Set、Map、List這幾個接口,關于List、Set、Map、Bag的語義,參考這篇post
Persistence Context 持久化上下文
???
Persistence Context是持久化框架需要維護的一個中間容器,其中會存放受管理對象的副本,例如從數據庫獲取的實體對象,或者調用持久化框架保存過的對象等
主要作用有:緩存(例如NHibernate的一級緩存概念)、支持Flush操作、輔助實現實體以及屬性的Dirty檢查等
JPA將persistence context分為2種類型:PersistenceContextType.TRANSACTION和 PersistenceContextType.EXTENDED。TRANSACTION類型(默認類型)的persistence context生命周期與transaction scope一致,例如事務開始時為生命周期的開始階段,事務提交或回滾時生命周期結束。EXTENDED類型的生命周期基本與EntityManager 一致,在EntityManager創建時開始,在EntityManager關閉時結束。實現Extended類型的persistence context時需要注意其生命周期可能跨越多個事務以及不在事務范圍內的情況,伴隨的是這些情況下對persistence context中實例對象生命周期以及相關操作的影響,例如version控制等
Entity Instance's Life Cycle 實例對象生命周期
實例對象的生命周期可以參考一下這篇post
實例對象的生命周期有4種狀態:
New: 新創建的實例對象,沒有identity值
Managed: 在持久化上下文中受管理的對象
Detached: 游離于持久化上下文之外的實例對象
Removed: 被刪除的實例對象
JPA中詳細定義了實例對象伴隨著EntityManager的各種操作時,生命周期狀態間的轉換關系
JPA聲明了entity instance life cycle的幾個callback方法:PrePersist、PostPersist、PreRemove、PostRemove、 PreUpdate、PostUpdate、PostLoad,對其語義進行了比較詳細的說明
Entity Relationships 實體關系
JPA定義了one-to-one、one-to-many、many-to-one、many-to-many 4種關系
Owning side, Inverse side 關系的所有方、反向方
在關聯關系的2方之中,關系的所有者一方為owning side,另一方為inverse side。關系的所有者可以這樣來理解,將所有者一方的實例刪除后,這個2方關系的任何信息都徹底消失。假如邏輯上表A有一個外鍵,引用自表B的主鍵(所 謂邏輯上是指數據庫中并沒有建立這個外鍵關系),如果將表B中某條數據b1刪除,A、B間相應實例對象的關聯關系可能并不會徹底消除,因為表A中可能還存 在某數據a1引用了b1的主鍵值,因此與B對應的實體類就不是owning side了
因此擁有外鍵的一方就是owning side了,這個在one-to-one的關系中比較清晰;one-to-many、many-to-one中,many的一方為owning side;many-to-many中任何一方都可以作為owning side
Owning side、inverse side將作為cascade相關操作的依據之一
JPA詳細定義了默認情況下對以下一些映射的處理方式:
雙向one-to-one;雙向one-to-many、many-to-one;單向single-valued(單向one-to-one、 many-to-one);雙向many-to-many;單向multi-valued(單向one-to-many、many-to-many)
Inheritance 繼承
Inheritance Mapping Strategies包括:
Single table per class hierarchy,使用一個discriminator column區別子類,優點是很好的支持多態關系、查詢,缺點是子類獨有的字段需要允許為null
Table per concrete entity class,缺點是不好支持多態關系,通常需要對各子類分別使用單獨的SQL或者使用UNION語句
Joined subclass,與table per concrete entity class區別是,將公共屬性的superclass使用一個表存儲,這種策略也能較好的支持多態關系,缺點是需要多個JOIN關系
詳細參考這篇post
Optimistic Locking and Concurrency 樂觀鎖及并發控制
JPA默認應用層將使用樂觀鎖機制
使用樂觀鎖時entity必須聲明一個version屬性,該字段的值由持久化框架自動維護,應用層不能修改。持久化框架可以引入其它機制實現樂觀鎖檢查,或者實現更細粒度的樂觀鎖控制,JPA不做要求
JPA的樂觀鎖機制是基于數據行的
JPA中聲明了Lock Mode,可以實現悲觀鎖效果,至于實現方式不作具體要求,只要確保不存在P1: dirty read、P2: non-repeatable read就行
LockModeType有READ和WRITE 2種
對于WRITE模式,在isolation level為read commited情況下數據庫可以確保不會出現P1、P2兩種狀況
READ模式一般使用數據庫的鎖實現,用它實現悲觀鎖效果
Query Language 查詢語言
類SQL的語法,但是帶上了較明顯的對象特征
聲明了SELECT、UPDATE、DELETE 3種語句
用簡單的例子瀏覽一下大致特性
1. 使用實體間的關聯關系
FROM ? Order ?o? JOIN ?o.lineItems?l? JOIN ?l.product?p
WHERE ?p.productType? = ? ' office_supplies '
JOIN子句不再需要ON條件部分了,因為對象之間已經定義了關聯關系
2. Collection Member Declarations
FROM ? Order ?o,? IN (o.lineItems)?l
WHERE ?l.product.productType? = ? ' office_supplies '
與1中的語句是等效的
FROM子句中為Order實體定義了別名o(Identification Variables);o.lineItems是集合類型的屬性,IN(o.lineItems) l 的語義是:Order實例對象的lineItems中必須有符合后續條件的,l則代表lineItems中的每個對象;WHERE子句進一步聲明了對l的 過濾條件
JPA中把l.product這種表達式叫做path expression(An identification variable followed by the navigation operator (.) and a state-field or association-field is a path expression)
path express中每個點號后面的內容,有三種類型:persistent field、single-valued relationship field、collection-valued relationship field。如果是collection-valued relationship field則只能在特定的場景 下使用
例如上面1、2例子中,如果lineItems不是集合類型,則這2個例子的語句都等效于下面的寫法(lineItems屬性改名為lineItem以區別于集合這個概念):
3.
FROM ? Order ?o
WHERE ?o.lineItem.product.productType? = ? ' office_supplies '
對path expression中的關聯關系,JPA規定使用INNER JOIN操作,因此上面語句等效前面的示例1、2
但當lineItems為collection-valued relationship field時,上面寫法不支持,必須采用1或2的寫法
特定場景 包括上面示例出來的JOIN子句、Collection Member Declarations這2種,還有Empty Collection Comparison Expressions、Collection Member Expressions中可以使用
4. Empty collection comparison expressions
FROM ? Order ?o
WHERE ?o.lineItems? IS ? [ NOT ] ?EMPTY
5. Collection Member Expressions
FROM ? Order ?o
WHERE ?:lineItem?MEMBER [OF] o.lineItems
:lineItem是一個變量,在應用中為該變量賦值一個lineItem實例對象,上面查詢的語義是:找到:lineItem對象關聯的Order實例對象
6. ALL and ANY Expressions
FROM ?Employee?emp
WHERE ?emp.salary? > ? ALL ?(
???? SELECT ?m.salary
???? FROM ?Manager?m
???? WHERE ?m.department? = ?emp.department)
ALL和ANY表達式用于子查詢
上面的emp.salary>ALL(...),表示emp.salary必須大于子查詢中返回的所有值;如果子查詢沒有符合條件的記錄,則emp.salary>ALL(...)這個條件為true
將上面例子中的關鍵字ALL改為ANY(或者是SOME)關鍵字,則表示emp.salary只要大于子查詢中返回的部分值就符合條件;如果子查詢沒有符 合條件的記錄,則emp.salary>ANY(...)這個條件為false;如果子查詢返回的結果全部都大于或等于emp.salary,則這 個條件為false
7. Constructor Expressions
使用constructor expressions可以指定使用特定的構造函數返回實例對象列表,而不是object數組的列表
FROM ?customer?c
WHERE ?c.lastname? = ? ' Coss ' ? AND ?c.firstname? = ? ' Roxane '
8. 再來幾個示例
Find all orders that have line items:
FROM ? Order ?o,? IN (o.lineItems)?l
或者:
SELECT ?oFROM ? Order ?o
WHERE ?o.lineItems? IS ? NOT ?EMPTY
Find all orders that have no line items:
FROM ? Order ?o
WHERE ?o.lineItems? IS ?EMPTY
通過上面這些例子可以看出JPA的查詢語言具備較強的對象表達能力
UPDATE、DELETE語句的主要目的是提供bulk update、delete操作
JPA中也聲明了一些函數,大部分為SQL標準中的一些基本函數
實現JPA規范的查詢語言時,需要重點處理的一個方面是多態查詢,語句中的實體類名有可能是abstract的或者supperclass,查詢解析器需 要能夠處理這種多態查詢。例如NHibernate(目前版本不知是否改成了Antlr來解析)在分析查詢語句時比較簡化處理,每遇到實體類都搜索是否有 子類存在,如果有則會為每個子類生成一個查詢語句,使用JOIN、UNION或者單獨執行每個語句再將結果合并(NHibernate不支持Union Subclass),只實現了部分多態能力。要實現完全的多態能力,面對的情況以及需要處理的東西都比較復雜
其它一些細節方面的東西也非常多,例如persistence context可能緩存了一些更新操作,等待Flush時回寫數據庫,但為了保證查詢結果的一致性,執行查詢前至少需要先將persistence context中相關實體的更新緩存運用到數據庫中
Metadata
詳細的元數據聲明規范,查閱JPA對annotation、XML descriptor的說明一節
總結
以上是生活随笔為你收集整理的JPA规范的主要内容的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EJB3.0 JPQL
- 下一篇: Jquery提交表单 Form.js官方