JPA基礎知識及JPA經常使用註解

JPA

  全稱Java Persistence API,經過JDK 5.0註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到數據庫中。java

  一、JPA和Hibernate的關係數據庫

  簡而言之編程

  • JPA 是一個規範或者接口框架

  • Hibernate 是 JPA 的一個實現ide

    JPA與Hibernate的關係相似於JDBC和JDBC驅動的關係,是對生產力的一種解放。咱們不需定製符合供應商提供的API,只需符合規範便可保證它的遷移性。工具

    JPA 是規範:JPA 本質上就是一種  ORM 規範,不是ORM 框架 —— 由於 JPA 並未提供 ORM 實現,它只是制訂了一些規範,提供了一些編程的 API 接口,但具體實現則由 ORM 廠商提供實現性能

    Hibernate 是實現,是一種ORM產品:Hibernate 除了做爲 ORM 框架以外,它也是一種 JPA 實現fetch

    從功能上來講, JPA 是 Hibernate 功能的一個子集this

  2、JPA 的供應商

      JPA 的目標之一是制定一個能夠由不少供應商實現的 API,目前Hibernate 3.2+、TopLink 10.1+ 以及 OpenJPA 都提供了 JPA 的實現spa

    Hibernate:JPA 的始做俑者就是 Hibernate 的做者。Hibernate 從 3.2 開始兼容 JPA

    OpenJPA:OpenJPA  是 Apache 組織提供的開源項目

    TopLink:TopLink 之前須要收費,現在開源了

  JPA的出現有兩個緣由:

    其一,簡化現有Java EE和Java SE應用的對象持久化的開發工做;

    其二,Sun但願整合對ORM技術,實現持久化領域的統一。

     三、JPA提供的技術:

    1)ORM映射元數據:JPA支持XML和JDK 5.0註解兩種元數據的形式,元數據描述對象和表之間的映射關係,框架據此將實體對象持久化到數據庫表中;

    2)JPA 的API:用來操做實體對象,執行CRUD操做,框架在後臺替咱們完成全部的事情,開發者從繁瑣的JDBC和SQL代碼中解脫出來。

    3)查詢語言:經過面向對象而非面向數據庫的查詢語言查詢數據,避免程序的SQL語句緊密耦合。

  四、JPA基本註解

    JPA 基本註解:@Entity, @Table, @Id, @GeneratedValue, @Column, @Basic,@Transient, @Temporal

    1)@Entity

          @Entity 標註用於實體類聲明語句以前,指出該Java 類爲實體類,將映射到指定的數據庫表。如聲明一個實體類 Customer,它將映射到數據庫中的 customer 表上。

    2)@Table

      當實體類與其映射的數據庫表名不一樣名時須要使用 @Table 標註說明,該標註與 @Entity 標註並列使用,置於實體類聲明語句以前,可寫於單獨語句行,也可與聲明語句同行。

     @Table 標註的經常使用選項是 name,用於指明數據庫的表名

      @Table標註還有一個兩個選項 catalog 和 schema 用於設置表所屬的數據庫目錄或模式,一般爲數據庫名。uniqueConstraints 選項用於設置約束條件,一般不須設置。

    3)@Id

      @Id 標註用於聲明一個實體類的屬性映射爲數據庫的主鍵列。該屬性一般置於屬性聲明語句以前,可與聲明語句同行,也可寫在單獨行上。

        @Id標註也可置於屬性的getter方法以前。

    4)@GeneratedValue

      @GeneratedValue  用於標註主鍵的生成策略,經過 strategy 屬性指定。默認狀況下,JPA 自動選擇一個最適合底層數據庫的主鍵生成策略:SqlServer 對應 identity,

              MySQL 對應 auto increment。在 javax.persistence.GenerationType 中定義瞭如下幾種可供選擇的策略:

        IDENTITY:採用數據庫 ID自增加的方式來自增主鍵字段,Oracle 不支持這種方式;

        AUTO: JPA自動選擇合適的策略,是默認選項;

        SEQUENCE:經過序列產生主鍵,經過 @SequenceGenerator 註解指定序列名,MySql 不支持這種方式

        TABLE:經過表產生主鍵,框架藉由表模擬序列產生主鍵,使用該策略可使應用更易於數據庫移植。

    5)@Basic

      @Basic 表示一個簡單的屬性到數據庫表的字段的映射,對於沒有任何標註的 getXxxx() 方法,默認即爲@Basic

      fetch: 表示該屬性的讀取策略,有 EAGER 和 LAZY 兩種,分別表示主支抓取和延遲加載,默認爲 EAGER.

      optional:表示該屬性是否容許爲null, 默認爲true

    6)@Column

      當實體的屬性與其映射的數據庫表的列不一樣名時須要使用@Column 標註說明,該屬性一般置於實體的屬性聲明語句以前,還可與 @Id 標註一塊兒使用。

      @Column 標註的經常使用屬性是 name,用於設置映射數據庫表的列名。此外,該標註還包含其它多個屬性,如:unique 、nullable、length等。

      @Column 標註的 columnDefinition 屬性: 表示該字段在數據庫中的實際類型.一般 ORM 框架能夠根據屬性類型自動判斷數據庫中字段的類型,

        可是對於Date類型仍沒法肯定數據庫中字段類型到底是DATE,TIME仍是TIMESTAMP.此外,String的默認映射類型爲VARCHAR,

        若是要將 String 類型映射到特定數據庫的 BLOB 或TEXT 字段類型.

      @Column標註也可置於屬性的getter方法以前

    7)@Transient

      表示該屬性並不是一個到數據庫表的字段的映射,ORM框架將忽略該屬性.

      若是一個屬性並不是數據庫表的字段映射,就務必將其標示爲@Transient,不然,ORM框架默認其註解爲@Basic

    8)@Temporal

      在覈心的 Java API 中並無定義 Date 類型的精度(temporal precision).  而在數據庫中,表示 Date 類型的數據有 DATE, TIME, 和 TIMESTAMP 三種精度

      (即單純的日期,時間,或者二者 兼備).在進行屬性映射時可以使用@Temporal註解來調整精度.

    9)用 table 來生成主鍵詳解

      將當前主鍵的值單獨保存到一個數據庫的表中,主鍵的值每次都是從指定的表中查詢來得到

      這種方法生成主鍵的策略能夠適用於任何數據庫,沒必要擔憂不一樣數據庫不兼容形成的問題。

/**
 * 註解@Entity映射的表名和類名同樣
 * 註解@Table:當實體類與其映射的數據庫表名不一樣名時使用。其中name,用於指明數據庫的表名 
 */
@Table(name="JPA_CUTOMER")
@Entity
public class Customer {
	private Integer id;
	private String name;
	private String email;
	private int age;
	private Date createTime;
	private Date birth;
 
	public Customer() {}
 
//用 table 來生成主鍵詳解(用的少):
//將當前主鍵的值單獨保存到一個數據庫的表中,主鍵的值每次都是從指定的表中查詢來得到
//這種方法生成主鍵的策略能夠適用於任何數據庫,沒必要擔憂不一樣數據庫不兼容形成的問題
/*	@TableGenerator(name="ID_GENERATOR", --name 屬性表示該主鍵生成的名稱,它被引用在@GeneratedValue中設置的generator 值中(即這兩個名字要同樣)
			table="jpa_id_generators",   --table 屬性表示表生成策略所持久化的表名
			pkColumnName="PK_NAME",      --pkColumnName 屬性的值表示在持久化表中,該主鍵生成策略所對應鍵值的名稱
			pkColumnValue="CUSTOMER_ID", --pkColumnValue 屬性的值表示在持久化表中,該生成策略所對應的主鍵(跟pkColumnName屬性能夠肯定惟一的一行,該行有不少列)
			valueColumnName="PK_VALUE",  --valueColumnName 屬性的值表示在持久化表中,該主鍵當前所生成的值,它的值將會隨着每次建立累加,(再加這個屬性能肯定惟一的那個點)
			allocationSize=100)          --allocationSize 表示每次主鍵值增長的大小, 默認值爲 50
	@GeneratedValue(strategy=GenerationType.TABLE,generator="ID_GENERATOR")*/
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Id
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
 
	/**
	 * 註解@Column 當實體的屬性與其映射的數據庫表的列不一樣名時須要使用
	 * nullable=false不能爲空
	 */
	@Column(name="NAME",length=50,nullable=false)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
 
	//若是 列名跟字段同樣如列名是email,則能夠不用寫,相關加了@Basic,但字段的屬性都是默認的
//	@Basic
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
 
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
 
	//---------------------------------------------------------------
	//註解@Temporal 調整時間精度 2018-11-11 10:11:11
	@Temporal(TemporalType.TIMESTAMP)
	public Date getCreateTime() {
		return createTime;
	}
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}
	
	//2018-11-11
	@Temporal(TemporalType.DATE)
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth = birth;
	}
 
	//工具方法. 不須要映射爲數據表的一列. 若是沒有加@Transient,則會出錯,由於沒有set方法
	@Transient
	public String getInfo(){
		return "name: " + name + ", email: " + email;
	}
 
}
相關文章
相關標籤/搜索