JPA學習筆記1——JPA基礎(轉)

1.JPA簡介:html

Java持久化規範,是從EJB2.x之前的實體Bean(Entity bean)分離出來的,EJB3之後再也不有實體bean,而是將實體bean放到JPA中實現。JPA是sun提出的一個對象持久化規範,各JavaEE應用服務器自主選擇具體實現,JPA的設計者是Hibernate框架的做者,所以Hibernate做爲Jboss服務器中JPA的默認實現,Oracle的Weblogic使用EclipseLink(之前叫TopLink)做爲默認的JPA實現,IBM的Websphere和Sun的Glassfish默認使用OpenJPA(Apache的一個開源項目)做爲其默認的JPA實現。java

JPA的底層實現是一些流行的開源ORM(對象關係映射)框架,所以JPA其實也就是java實體對象和關係型數據庫創建起映射關係,經過面向對象編程的思想操做關係型數據庫的規範。sql

2.JPA的持久化策略文件:數據庫

根據JPA規範要求,在實體bean應用中,須要在應用類路徑(classpath)的META-INF目錄下加入持久化配置文件——persistence.xml,該文件就是持久化策略文件。其內容以下:apache

 

[xhtml]  view plain  copy
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">  
  3.   <persistence-unit name="持久化單元名" transaction-type="JTA">  
  4.       <jta-data-source>使用JCA部署在javaEE服務器上的數據源JNDI</jta-data-source>  
  5.         <!--指定JPA實現提供者,不指定就採用JavaEE服務器默認的JPA提供者,這裏以        OpenJPA爲例-->  
  6. <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>  
  7. <class>實體bean全路徑名</class>  
  8. ……  
  9.     <properties>  
  10.               <!--配置JPA實現提供者的一些信息-->  
  11.     </properties>  
  12.   </persistence-unit>  
  13. </persistence>  

 

 

注意:能夠在持久化策略文件中配置多個持久化單元persistence-unit,在使用分佈式數據庫時常常配置多個持久化單元。編程

3.實體Bean的開發:服務器

JPA規範中定義的實體bean開發的基本規範:app

(1).在實體bean上添加」@Entity」註解,標識該bean爲實體bean。框架

(2).實體bean必須序列化。分佈式

(3).使用」@Table(name=數據庫表名)」註解,標識該實體bean映射到關係型數據庫中的表名,若是不指定則JPA實現會自動生成默認的表名稱。

(4).必須有一個使用」@Id」註解標識的主鍵,如指定自增主鍵的寫法爲:

 

[java]  view plain  copy
 
  1. @Id  
  2. @Column(name=」列名」)  
  3. @GeneratedValue(Strategy=GenerationType.Auto)  
  4. private int id;  

 

 

注意:@Id和@GeneratedValue兩個註解必須同時使用,標識了註解以後,要主鍵的生成策略。

(5).Bean的其餘屬性使用」@Column(name=列名)」註解,指定該屬性映射到數據庫表中的列名,若是不指定在JPA實現會自動生成默認的列名。

(6).實體Bean必須嚴格遵循JavaBean的規範,提供無參的默認構造方法,屬性提供set和get方法。

(7).最好重寫hashcode()和equals()方法,實體bean的惟一標識是主鍵,所以,使用實體bean的主鍵來比較。

4.實體bean的主鍵生成策略:

實體bean的註解生成策略使用」@GeneratedValue」註解來指定主鍵的生成策略,默認使用Auto自增的策略,JPA不支持Hibernate的UUID主鍵生成策略,若要使用Hibernate的UUID作主鍵方式,方法以下:

(1).將Hibernate.annotation jar包加入到類路徑下。

(2).在使用」@Id」的字段上同時加入以下的註解:

 

[java]  view plain  copy
 
  1. @GeneratedValue(generator=」UUID主鍵生成策略」)  
  2. @GenericGenerator(name=」 UUID主鍵生成策略」, strategy=」uuid」)  

 

 

5.JPA開發的注意事項:

JPA支持xml方式和註解方式,目前隨着註解方式愈來愈成熟和流行,開發JPA時候,基本都只用註解方式,所以必須在JavaEE5以上版本才行,由於之前的版本沒有對註解的支持。

和xml文件相比,java註解的優缺點:

優點:

(1).描述符減小,大大提升開發效率。
(2).編譯期校驗,錯誤的註解在編譯期間就會報錯。

(3).註解在java代碼中,從而避免了額外的文件維護工做。

(4).註解被編譯成java字節碼,消耗的內存小,讀取速度快,每每比xml配置文件解析快幾個數量級,利用測試和維護。

缺點:

(1).配置信息分散,不利於集中維護管理。

(2).改動時涉及到了程序源代碼,須要找到類的源代碼才能夠,並且必須經過編譯這一步。相比較之下xml文件可能不須要找到類源碼,同時也不須要從新編譯。

6.JPA註解的使用注意事項:

JPA的註解支持字段註解,也支持屬性註解。

字段註解:直接在變量上加註解。

屬性註解:在set/get方法上加註解。

注意:無論使用哪一種註解方式,在一個實體類中,不能混用兩種註解方式。

7.JPA其餘的經常使用註解:

除了@Entity、@Id、@Table、@Column、@GeneratedValue等註解之外,JPA還有如下經常使用的註解:

(1).@Temporal:主要用於標註時間類型,在javax.persistence.TemporalType枚舉中定義了3種時間類型:

a.DATE:等同於java.sql.Date;

b.TIME:等同於java.sql.Time;

c.TIMESTAMP:等同於java.sql.Timestamp;

(2).@Transient:實體bean中默認全部的字段都會被映射到數據庫中,若是某個屬性不想被映射到數據庫中,則須要對其加該註解。

(3).@Lob:將屬性持久化爲Blob或者Clob類型,爲大數據類型。

(4).@Basic:通常能夠用來控制是否進行延遲加載,用法示例:

延遲加載:@Basic(fetch=FetchType.Lazy)

非延遲加載:@Basic(fetch=FetchType.EAGER)

(5).@NamedQueryies和@NamedQuery:在實體Bean上定義命名查詢。

名稱查詢相似於jdbc中的PrepareStatement,是在數據庫中預編譯的查詢,能夠大大提升查詢效率,用法以下:

 

[java]  view plain  copy
 
  1. @NamedQueries({  
  2.        @NamedQuery(name=」命名查詢名字」,query=JPQL查詢語句),  
  3.        ……  
  4. })  

 

 

(6).@OneToOne:

一對一映射註解,雙向的一對一關係須要在關係維護端(owner side)的@OneToOne註解中添加mappedBy屬性,建表時在關係被維護端(inverse side)創建外鍵指向關係維護端的主鍵列。

用法:@OneToOne(optional=true,casecade=CasecadeType.ALL,mappedBy=」被維護端外鍵」)

(7).@OneToMany:

一對多映射註解,雙向一對多關係中,一端是關係維護端(owner side),只能在一端添加mapped屬性。多端是關係被維護端(inverse side)。建表時在關係被維護端(多端)創建外鍵指向關係維護端(一端)的主鍵列。

用法:@OneToMany(mappedBy = "維護端(一端)主鍵", cascade=CascadeType.ALL)

注意:在Hibernate中有個術語叫作維護關係反轉,即由對方維護關聯關係,使用inverse=false來表示關係維護放,在JPA的註解中,mappedBy就至關於inverse=false,即由mappedBy來維護關係。

(8). @ManyToOne:

多對一映射註解,在雙向的一對多關係中,一端一方使用@OneToMany註解,多端的一方使用@ManyToOne註解。多對一註解用法很簡單,它不用維護關係。

用法:@ManyToOne(optional = false, fetch = FetchType.EAGER)

(9).@ManyToMany:

多對多映射,採起中間錶鏈接的映射策略,創建的中間關係表分別引入兩邊的主鍵做爲外鍵,造成兩個多對一關係。雙向的多對多關係中,在關係維護端(owner side)的@ManyToMany註解中添加mappedBy屬性,另外一方是關係的被維護端(inverse side),關係的被維護端不能加mappedBy屬性,建表時,根據兩個多端的主鍵生成一箇中間表,中間表的外鍵是兩個多端的主鍵。

用法:關係維護端——>@ManyToMany(mappedBy=」另外一方的關係引用屬性」)

關係被維護端——>@ManyToMany(cascade=CascadeType.ALL ,fetch = FetchType.Lazy)

8.JPA的一對一關聯映射:

在JPA中兩個實體之間是一一對應的關係稱爲一對一關聯關係映射,如人和身份證號關係。

(1).一對一單向關聯映射:

只能從映射端查找到隨關聯的一方,而不能反向查找。

在關聯映射方關聯屬性上添加@OneToOne註解。

(2).一對一雙向關聯映射:

能夠雙向查找關聯關係的實體。

關係維護端:在關聯屬性或字段上添加@OneToOne註解,同時制定@OneToOne註解的mappedBy屬性。

關係被維護端:在關聯屬性或字段上添加@OneToOne註解。

9.一對一關聯映射兩種策略:

(1).一對一主鍵關聯:

一對一關聯映射中,主鍵關聯策略不會在兩個關聯實體對應的數據庫表中添加外鍵字段,兩個實體的表公用同一個主鍵(主鍵相同),其中一個實體的主鍵既是主鍵又是外鍵。

主鍵關聯映射:在實體關聯屬性或方法上添加@OneToOne註解的同時添加@PrimaryKeyJoinColumn註解(在一對一註解關聯映射的任意一端實體添加便可)。

(2).一對一惟一外鍵關聯:

一對一關聯關係映射中,惟一外鍵關聯策略會在其中一個實體對應數據庫表中添加外鍵字段指向另外一個實體表的主鍵,也是一對一映射關係中最經常使用的映射策略。

惟一外鍵關聯:在關聯屬性或字段上添加@OneToOne註解的同時添加@JoinColumn(name=」數據表列名」,unique=true)註解。

10.一對多關聯映射:

在JPA中兩個實體之間是一對多關係的稱爲一對多關聯關係映射,如班級和學生關係。

(1).一對多單向關聯映射:

在一對多單向關聯映射中,JPA會在數據庫中自動生成公有的中間表記錄關聯關係的狀況。

在一端關聯集合屬性或字段上添加@OneToMany註解便可。

(2).一對多雙向關聯映射:

在一對多雙向關聯映射中,JPA不會在數據庫中生成公有中間表。

在一端關聯集合屬性或字段上添加@OneToMany註解,同時指定其mappedBy屬性。

在多端關聯屬性或字段上添加@ManyToOne註解。

注意:一對多關係映射中,mappedBy只能添加在OneToMany註解中,即在多端生成外鍵。

11.多對多關聯映射:

在JPA中兩個實體之間是多對多關係的稱爲多對多關聯關係映射,如學生和教師關係。

(1).多對多單向映射:

在其中任意實體一方關聯屬性或字段上添加@ManyToMany註解。

(2).多對多雙向映射:

關係維護端關聯屬性或字段上添加@ManyToMany註解,同時指定該註解的mappedBy屬性。

關係被維護端關聯屬性或字段上添加@ManyToMany註解。

12.JPA中實體繼承映射策略:

在JPA中,實體繼承關係的映射策略共有三種:單表繼承策略、Joined策略和Table_PER_Class策略。

(1).單表繼承策略:

單表繼承策略,父類實體和子類實體共用一張數據庫表,在表中經過一列辨別字段來區別不一樣類別的實體。具體作法以下:

a.在父類實體的@Entity註解下添加以下的註解:

 

[java]  view plain  copy
 
  1. @Inheritance(Strategy=InheritanceType.SINGLE_TABLE)  
  2. @DiscriminatorColumn(name=」辨別字段列名」)  
  3. @DiscriminatorValue(父類實體辨別字段列值)  

 

 

b.在子類實體的@Entity註解下添加以下的註解:

 

[java]  view plain  copy
 
  1. @DiscriminatorValue(子類實體辨別字段列值)  

 

 

(2).Joined策略:

Joined策略,父類實體和子類實體分別對應數據庫中不一樣的表,子類實體的表中只存在其擴展的特殊屬性,父類的公共屬性保存在父類實體映射表中。具體作法:

只需在父類實體的@Entity註解下添加以下註解:

 

[java]  view plain  copy
 
  1. @Inheritance(Strategy=InheritanceType.JOINED)  

 

 

子類實體不須要特殊說明。

(3).Table_PER_Class策略:

Table_PER_Class策略,父類實體和子類實體每一個類分別對應一張數據庫中的表,子類表中保存全部屬性,包括從父類實體中繼承的屬性。具體作法:

只需在父類實體的@Entity註解下添加以下註解:

 

[java]  view plain  copy
 
  1. @Inheritance(Strategy=InheritanceType.TABLE_PER_CLASS)  

 

 

子類實體不須要特殊說明。

相關文章
相關標籤/搜索