JPA的總體思想和現有Hibernate、TopLink,JDO等ORM框架
Posted on 2011-02-21 10:22 edsion 閱讀(758) 評論(0) 編輯 收藏 所屬分類: Hibernate4. JPA 1.0
4.1 ORM: 單表,1:1, 1:n, n:m
4.2 其他: PK生成策略,延遲加載策略,級聯(cascading)選項
4.3 JPQL: 單表查詢,多表結合查詢
1. 概述
Java Persistence API作為JavaEE5.0平臺的標準的ORM規范,將得到所有JavaEE所有服務器的支持。
JPA由EJB3.0軟件開發組專家開發,作為JSR-220的實現的一部分。
目前hibernate、Toplink以及OpenJPA都提供了JPA的支持。
JPA包括三個方面技術:
ORM映射元數據,JPA支持XML與JDK5.0注釋,元數據描述對象與表之間的映射關系,框架可以將實體對象持久化到數據庫當中。
JPA持久化API,用來操作實體對象,執行curd操作,框架在后臺替我們完成了所有的事情,開發者可以從JDBC和SQL代碼中解脫出來。
查詢語言,這是持久化操作很重要的一個概念。通過面向對象而非面向數據庫的查詢數據,避免程序與SQL的緊密耦合。
2. 實體對象
訪問數據庫之前,我們總是要設計在應用層承載數據的領域對象,ORM將它們持久化到數據庫當中。
按照JPA規范實體必須具備以下要求:
必須使用javax.persistence.Entity注解或者使用XML映射文件中相對應的元素。
必須具備一個不帶參數的構造函數,類不能聲明成final,方法和持久化的屬性也不能聲明成final,并且被持久化的屬性訪問修飾符不能為public。
如果游離狀的實體需要以值的方式進行傳遞,如EJB的Session bean,則必須實現Serializable接口。
3. 基本注解
@Entity:將領域模型標注為一個實體,默認情況下類為表名,可以通過name屬性重新指定。
@Id:屬性對應表的主鍵。
@Column:屬性對應表的字段。
@GenaratedValue:主鍵生成策略,通過startage屬性指定。在4.0會解釋主鍵生成策略。
4. 主鍵生成策略
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface GeneratedValue {
GenerationType strategy() default AUTO;
String generator() default "";
}
IDENTITY:主鍵由數據庫自動生成。
AUTO:JPA自動選擇合適的主鍵生成策略,默認選線。
SEQUENCE:通過序列產生主鍵,條件是數據庫必須支持序列。
TABLE:通過表產生主鍵,使用該策略更易于數據庫的移值。
5. 實體關系
實體之間的關系有一對一,一對多,多對一,多多對。關系是多態的。
多對一
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
}
一對一
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToOne {
Class targetEntity() default void.class;
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
String mappedBy() default "";
}
6. 雙向關聯特性
雙向關系的的反向端必須通過OnToOne,OnToMany或者ManyToMany注解的MappedBy元素必須指向它的持久端。MappendBy表述主控端的屬性或字段。
一對多,多對一雙向關系中的多端必須是持久端,因此不能再ManyToOne中使用MappedBy屬性。
對于一對一雙向關聯關系,包括對應的外鍵(foreign key)那一段時持久化。
對于多對多雙向關聯關系都是持久端。
7. 延遲加載
FetchType.EAGER:代表立即加載。
FetchType.LAYZ:代表延遲加載策略。
8. 多級級聯
REFRESH指定當你在訪問期間,如果數據庫數據發生改變時,你的數據是否更 新。
PERSIST指定在保存1數據的時是否會同時保存級聯的n數據。
MERGE指定當1處于游離狀態被修改了,n的數據也會被修改。
REMOVE指定在刪除1的同時是否刪除與之級聯的n數據。
ALL指定包含所有的級聯的N方。
9. Java Persistence Query language
基于首次在EJB2.0引用的EJB查詢語言,java持久化查詢語言是一種可移植的查詢語言。旨在以面向對象表達式語言的表達式,將SQL語法和簡單查詢語義綁定在一起.使用這種語言編寫的查詢是可移植的,可以被編譯成所有主流數據庫服務器上的SQL.
10JPA2.0與JPA1.0
JPA2.0也跟Hibernate一樣,也分為一級緩存,二級緩存,而JPA1.0不支持二級緩存,二級緩存是跨事物場景的。當二級緩存有效時,你就不能通過事物來保護并發數據,而只能依靠鎖的策略。
11 事物與EntityManager
EntityManager對象事物管理分為二種,由JTA和RESOURCE_LOCAL來控制。
JTA EntityManager一般在容器里面使用,而RESOURCE_LOCAL(應用托管的EntityManager)數據庫本地化事物,一般在J2SE環境下使用。
通過容器來傳遞PersistenceContext而不是通過程序來自己傳遞EntityManager,它的生命周期由容器進行管理。
在J2SE環境下,RESOURCE_LOCAL由程序來創建EntityManagerFactory,并由EntityManagerFactory來創建EntityManger,這種方式就是RESOURCE_LOCAL的基本使用方式。
12 監聽實體調用
監聽實體主要有PostLoad , PostPersist , PostRemove , PostUpdate, pre-persist , pre-remove 等。調用如下:
public class UserListeners {
@PostRemove
public void dothing(User user) {
System.out.println("加載..........." + user.getUserName());
}
} @Entity
@org.hibernate.annotations.Entity(dynamicInsert = true)
@EntityListeners(UserListeners.class)
public class User implements Serializable{
………………..
}
13 樂觀鎖定
樂觀鎖定它可以確保在實體的狀態從數據庫讀取出來,在沒有中間插入的其它事物更改了與這個實體對應數據庫記錄的情況下,才把更新后實體的狀態更新到數據庫。它確保對數據的更新和刪除與數據庫的當前狀態保持一致,并且不會丟失中間的修改。如果應用程序想啟用實體的樂觀鎖,就必須為實體指定version屬性。如果沒有將樂觀鎖作為實體狀態的一部分進行定義,應用程序就要自己去維護數據的完整性。
直接映射
實體的生命周期
EntityManager用于管理實體實例的生命周期,一個實體實例可以分為new,managed,detached,或remove
一個新創立的實體實例沒有持久化標識,并且還沒有跟持久化上下相關聯。
一個受管的實體實例有一個正與持久化上下文相關聯的持久化標識。
一個脫管的實體實例有持久化標識,但是這個標識沒有跟持久化上下文相關聯。
被刪除的實體實例有持久化標示,并且與持久化上下文相關聯,但是已經計劃從數據庫中刪除。
@Enumerated
@Temporal
@Lob
@Transient
關系映射
@OneToOne
@ManyToOne
@OneToMany
@ManyToMany
@MapKey
@OrderBy
繼承
@DiscriminatorColumn
@DiscriminatorValue
@MappedSuperclass
@AssociationOverride
@AssociationOverrides
@AttributeOverride
@AttributeOverrides
鎖定
@PostPersist
@PreRemove
@PostRemove
@PreUpdate
@PostUpdate
@PostLoad
@EntityListeners
@ExcludeDefaultListeners
@ExcludeSuperclassListeners
查詢
@NamedQueries
@NamedNativeQuery
@NamedNativeQueries
@QueryHint
@ColumnResult
@EntityResult
@FieldResult
@SqlResultSetMapping
@SqlResultSetMappings
綜合上面調研的內容,上傳一個基本(簡單)的例子。該例子主要描述了JPA雙向一對一,雙向一對多,雙向多對多,單向一對一,單向一對多,單向多對一與單向多對多,測試代碼中使用了級聯、延遲加載策略,單表查詢、多表查詢JPQL。JPA版本采用Hibernate3.2