基本注解
@Entity
標注用於實體類聲明語句之前,指出該Java類為實體類,將映射到指定的數據庫表。如聲明一個實體類Customer,將它映射到數據的coustomer表上。
package com.dxsoft.jpa.helloword; import javax.persistence.Entity; @Entity public class Person { //... }
@Table
- 當實體類與其映射的數據庫表名不同名時,需要使用@Table標注說明,該注解與@Entity標注並列使用,置於實體類聲明語句之前,可寫於單獨語句行,也可與聲明數據同行。
- @Table標注的常用選項是name,用於指明數據庫的表名。
- @Table標注還有兩個可選項catalog和schema用於設置表所屬的數據庫目錄或模式,通常為數據庫名。
- uniqueConstraints選項用於設置約束條件,通常不須設置。
package com.dxsoft.jpa.helloword; import javax.persistence.Entity; import javax.persistence.Table; @Entity @Table(name = "jpa_person") public class Person { //。。。 }
@Id
- @Id標注用於聲明一個實體類的屬性映射為數據庫的主鍵列。該屬性通常置於屬性聲明語句之前,可與聲明數據同行,也可卸載單獨行上。
- @Id標注也可置於屬性的getter方法之前。
@GeneratedValue
- @GeneratedValue用於標注主鍵的生成策略,通過strategy屬性指定。默認情況下,JPA自動選擇一個最合適底層數據庫的主鍵生成策略:SqlServer對應identity,MySql對飲auto increment。
- 在javax.persistence.GenerationType中定義了以下幾種可供選擇的策略:
- --- IDENTITY:采用數據庫ID自增長的方式來自增主鍵字段,Oracle不支持這種方式(oracle12g后,應該支持了。);
- --- AUTO:JPA自動選擇合適的策略,是默認選項;
- --- SEQUENCE:通過序列產生主鍵,通過@SequenceGenerator注解指定序列名,MySql不支持這種方式。
- --- TABLE:通過表產生鍵,框架借助由表模擬序列產生主鍵,使用該策略可以使應用更易於數據庫移植。
@Column
- 當實體的屬性與其映射的數據庫表的列不同名時需要使用@Column標注說明,該屬性通常置於實體的屬性聲明語句之前,還可與@Id標注一起使用。
- @Column標注的常量屬性是name,用於設置映射數據庫表的列名。此外,該注解還包含其他多個屬性,比如:unique,nullable,length等。
- @Column標注的columnDefinition屬性:表示該字段在數據中的實際類型,通常ORM框架可以根據屬性類型自動判斷數據中的字段的類型,但是對於Date類型仍無法確定數據庫中字段類型究竟是Date,Time還是Timestamp。此外,String的默認類型為varchar,如果要將String類型映射到特定數據庫的BLOB或Text字段類型。
- @Column標注也可以置於屬性的getter方法之前。
@Basic
- @Basic表示一個簡單的屬性到數據庫表的字段的映射,對於沒有任何標注的getXxx()方法,默認即為Basic
- fetch:表示該屬性的讀取策略,有EAGER和LAZY兩種,分別表示主支抓取和延遲加載,默認為EAGER
- optional:表示該屬性是否允許為null,默認為true。
@Transient
- 表示該屬性並非一個到數據庫表的字段的映射,ORM框架將忽略該屬性。
- 如果一個屬性並非數據庫的字段映射,就務必將其標示為@Transient,否則,ORM框架默認其注解為@Basic。
假設Person類需要擴展一個幫助方法,getUserInfo()
// 幫助方法,不希望保存到數據庫,但是需要動態獲取Customer對象的屬性。 public String getUserInfo() { return "username:" + fullName + ",age:" + age; }
此時,運行時拋出異常。
解決上邊需求,而且又不拋異常的方案:需要在getUserInfo()方法上添加注解@Transient
@Temporal
- 在核心的JAVA API中並沒有定義Date類型的精度(temporal precision)。而在數據庫中,表示Date類型的數據類型有DATE,TIME和TEIMSTAMP三種精度(即單純的日期,時間,或者兩者兼備)。在運行屬性映射是可使用
- @Temporal注解來調整Date精度。
修改項目:
1)修改Person實體類,新增birth,createTime字段

package com.dxsoft.jpa.helloword; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Transient; @Entity @Table(name = "jpa_person") public class Person { private Integer id; private String fullName; private int age; private Date birth; private Date createTime; public Person() { } @GeneratedValue(strategy = GenerationType.AUTO) @Id public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "full_name", nullable = false, length = 64) public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } // 幫助方法,不希望保存到數據庫,但是需要動態獲取Customer對象的屬性。 @Transient public String getUserInfo() { return "username:" + fullName + ",age:" + age; } @Override public String toString() { return "Person [id=" + id + ", fullName=" + fullName + ", age=" + age + "]"; } }
2)修改測試main函數
此時,刪除mysql數據中的jpa_person表,重新運行。
運行日志:

Hibernate: create table hibernate_sequence ( next_val bigint ) engine=InnoDB Hibernate: insert into hibernate_sequence values ( 1 ) Hibernate: create table jpa_person ( id integer not null, age integer not null, birth datetime, createTime datetime, full_name varchar(64) not null, primary key (id) ) engine=InnoDB Fri Jun 15 12:25:35 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. Hibernate: select next_val as id_val from hibernate_sequence for update Hibernate: update hibernate_sequence set next_val= ? where next_val=? Hibernate: insert into jpa_person (age, birth, createTime, full_name, id) values (?, ?, ?, ?, ?) 六月 15, 2018 12:25:35 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://127.0.0.1:3306/jpa] complete..
此時查看mysql中表
顯然這里的createTime可以使用,但是birth的日期精度要求是短日期格式就可以。
使用@Temporal注解來調整Date精度
修改person.java實體類
刪除mysql中數據庫jpa_person表,重新運行查看數據表結構,及數據。
運行日志:

Hibernate: create table hibernate_sequence ( next_val bigint ) engine=InnoDB Hibernate: insert into hibernate_sequence values ( 1 ) Hibernate: create table jpa_person ( id integer not null, age integer not null, birth date, createTime datetime, full_name varchar(64) not null, primary key (id) ) engine=InnoDB Fri Jun 15 12:30:16 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. Hibernate: select next_val as id_val from hibernate_sequence for update Hibernate: update hibernate_sequence set next_val= ? where next_val=? Hibernate: insert into jpa_person (age, birth, createTime, full_name, id) values (?, ?, ?, ?, ?) 六月 15, 2018 12:30:16 下午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://127.0.0.1:3306/jpa] complete..
用table來生成數據表的主鍵
- 將當前主鍵的值單獨保存到一個數據的表中,主鍵的值每次都是從指定的表中查詢獲得
- 這種方式生成主鍵的策略可以適用於任何數據庫,不必擔心不同數據不兼容造成的問題。
1)修改Person.java
@TableGenerator( name = "person_id_generator", table = "jpa_id_generator", pkColumnName = "pk_name", pkColumnValue = "person_id", valueColumnName = "pk_value", initialValue = 1, allocationSize = 100) @GeneratedValue( strategy = GenerationType.TABLE, generator = "person_id_generator") @Id public Integer getId() { return id; } public void setId(Integer id) { this.id = id; }
2)刪除已經存在表jpa_person,重新執行三次main函數:
3)發現新增了jpa_id_generator表,表jpa_id_generator中也有了記錄:
jpa_person記錄為:
jpa_id_generator記錄為: