JPA實(shí)體類(lèi)注解,看這篇就全會(huì)了
哈嘍,大家好,我是指北君。
今天給大家介紹一下 JPA 實(shí)體類(lèi)中的注解,希望能對(duì)大家有幫助。
基本注解
@Entity
標(biāo)注于實(shí)體類(lèi)聲明語(yǔ)句之前,指出該 Java 類(lèi)為實(shí)體類(lèi),將映射到指定的數(shù)據(jù)庫(kù)表。
- name(可選):實(shí)體名稱(chēng)。 缺省為實(shí)體類(lèi)的非限定名稱(chēng)。該名稱(chēng)用于引用查詢(xún)中的實(shí)體。
不與 @Table 結(jié)合時(shí),表名默認(rèn)為類(lèi)名的 SnakeCase(蛇形命名法),若使用name屬性,則表名為 name 值。
@Table
當(dāng)實(shí)體類(lèi)與其映射的數(shù)據(jù)庫(kù)表名不同名時(shí)需要使用@Table標(biāo)注說(shuō)明,該標(biāo)注與@Entity標(biāo)注并列使用,置于實(shí)體類(lèi)聲明語(yǔ)句之前。
- name:用于指明數(shù)據(jù)庫(kù)的表名。
- catalog、schema:用于設(shè)置表所屬的數(shù)據(jù)庫(kù)目錄或模式,通常為數(shù)據(jù)庫(kù)名。Mysql不支持catalog,schema是數(shù)據(jù)庫(kù)名。一般不需要設(shè)置。
- uniqueConstraints:用來(lái)批量命名唯一鍵,其作用等同于多個(gè):@Column(unique = true),一般不需要設(shè)置。
@Basic(未加注解的默認(rèn)注解)
表示一個(gè)簡(jiǎn)單的屬性到數(shù)據(jù)庫(kù)表的字段的映射,對(duì)于沒(méi)有任何注解的屬性,默認(rèn)即為 @Basic 。
- fetch: 表示該屬性的讀取策略,其中 EAGER (默認(rèn))表示立即加載,LAZY 表示延遲加載。
- optional:表示該屬性是否允許為 null ,默認(rèn)為 true 。
@Transient
表示該屬性并非一個(gè)到數(shù)據(jù)庫(kù)表的字段的映射,ORM 框架將忽略該屬性。
如果一個(gè)屬性并非數(shù)據(jù)庫(kù)表的字段映射,就務(wù)必將其標(biāo)示為@Transient,否則,ORM框架默認(rèn)其注解為@Basic 。
@Column
當(dāng)實(shí)體的屬性與其映射的數(shù)據(jù)庫(kù)表的列不同名時(shí)需要使用@Column 標(biāo)注說(shuō)明,該注解通常置于實(shí)體的屬性前或?qū)傩缘膅etter方法之前,還可與 @Id 標(biāo)注一起使用。
- name:用于設(shè)置映射數(shù)據(jù)庫(kù)表的列名。
- unique:是否是唯一標(biāo)識(shí),默認(rèn)為 false(不唯一)
- nullable:否允許為 null,默認(rèn)為true(null)
- insertable:表示在 ORM 框架執(zhí)行插入操作時(shí),該字段是否應(yīng)出現(xiàn) INSERT 語(yǔ)句中,默認(rèn)為true
- updatable:表示在 ORM 框架執(zhí)行更新操作時(shí),該字段是否應(yīng)該出現(xiàn)在 UPDATE 語(yǔ)句中,默認(rèn)為 true。對(duì)于一經(jīng)創(chuàng)建就不可以更改的字段,該屬性非常有用,如對(duì)于birthday字段?;蛘邉?chuàng)建時(shí)間/注冊(cè)時(shí)間(可以將其設(shè)置為 false 不可修改)。
- length:數(shù)據(jù)長(zhǎng)度,僅對(duì)String類(lèi)型的字段有效,默認(rèn)值255
- precision、scale:表示精度,當(dāng)字段類(lèi)型為double時(shí),precision表示數(shù)值的總長(zhǎng)度,scale表示小數(shù)點(diǎn)所占的位數(shù),默認(rèn)值均為0。
- columnDefinition:表示該字段在數(shù)據(jù)庫(kù)中的實(shí)際類(lèi)型。通常ORM框架可以根據(jù)屬性類(lèi)型自動(dòng)判斷數(shù)據(jù)庫(kù)中字段的類(lèi)型,但是如果要將 String 類(lèi)型映射到特定數(shù)據(jù)庫(kù)的 BLOB 或 TEXT 字段類(lèi)型,該屬性非常有用。
@Id
用于聲明一個(gè)實(shí)體類(lèi)的屬性映射為數(shù)據(jù)庫(kù)的主鍵列。
@GeneratedValue
- JPA通用策略生成器,通過(guò) strategy 屬性指定。
- 定義了以下幾種可供選擇的策略:
AUTO:JPA 自動(dòng)選擇合適的策略,是默認(rèn)選項(xiàng);
IDENTITY:采用數(shù)據(jù)庫(kù) ID自增長(zhǎng)的方式來(lái)自增主鍵字段,Oracle 不支持這種方式;
SEQUENCE:通過(guò)序列產(chǎn)生主鍵,通過(guò) @SequenceGenerator 注解指定序列名,MySql 不支持這種方式
TABLE:通過(guò)表產(chǎn)生主鍵,框架借由表模擬序列產(chǎn)生主鍵,使用該策略可以使應(yīng)用更易于數(shù)據(jù)庫(kù)移植。該策略一般與另外一個(gè)注解一起使用@TableGenerator。
- 默認(rèn)情況下,JPA 自動(dòng)選擇一個(gè)最適合底層數(shù)據(jù)庫(kù)的主鍵生成策略:SqlServer 對(duì)應(yīng) IDENTITY,MySQL 對(duì)應(yīng) AUTO。
- generator:使用指定的主鍵生成器時(shí),這里設(shè)置為生成器名稱(chēng)。
@GenericGenerator
自定義主鍵生成策略
- name:生成器名稱(chēng)
- strategy:預(yù)定義的 Hibernate 策略或完全限定的類(lèi)名。
其他注解
@Enumerated
直接映射枚舉類(lèi)型的字段。
- value:
ORDINAL:映射到數(shù)據(jù)庫(kù)字段為數(shù)字(默認(rèn))
String:映射到數(shù)據(jù)庫(kù)字段為字符串
@Temporal
對(duì)于日期時(shí)間屬性映射時(shí),可使用 @Temporal 注解來(lái)調(diào)整精度。
- DATE:日期
- TIME:時(shí)間
- TIMESTAMP:日期時(shí)間
@DynamicInsert、@DynamicUpdate
- @DynamicInsert:設(shè)置為true,表示insert對(duì)象的時(shí)候,生成動(dòng)態(tài)的insert語(yǔ)句,如果這個(gè)字段的值是null就不會(huì)加入到insert語(yǔ)句中。
- @DynamicUpdate:設(shè)置為true,表示update對(duì)象的時(shí)候,生成動(dòng)態(tài)的update語(yǔ)句,如果這個(gè)字段的值是null就不會(huì)被加入到update語(yǔ)句中。
@Access
指定實(shí)體的訪問(wèn)模式(Access mode),包括AccessType.FIELD及AccessType.PROPERTY。
- AccessType.FIELD: 字段訪問(wèn)(@Column注解在屬性上),通過(guò)字段來(lái)獲取或設(shè)置實(shí)體的狀態(tài),getter和setter方法可能存在或不存在。這樣JPA默認(rèn)的訪問(wèn)類(lèi)型為AccessType.FIELD。
- AccessType.PROPERTY: 屬性訪問(wèn)(@Column注解在get方法上),持久化屬性必須有g(shù)etter和setter方法,屬性的類(lèi)型由getter方法的返回類(lèi)型決定,同時(shí)必須與傳遞到setter方法的單個(gè)參數(shù)的類(lèi)型相同。這樣JPA默認(rèn)的訪問(wèn)類(lèi)型為AccessType.PROPERTY。
復(fù)合主鍵
@EmbeddedId + @Embeddable
當(dāng)需要多個(gè)屬性作為復(fù)合主鍵時(shí),可以把該屬性做為一個(gè)內(nèi)部類(lèi)嵌套在實(shí)體類(lèi)中,使用@EmbeddedId + @Embeddable實(shí)現(xiàn):
- @EmbeddedId:復(fù)合主鍵
- @Embeddable:注釋Java類(lèi)的,表示類(lèi)是嵌入類(lèi):
必須要實(shí)現(xiàn)Serializable接口
需要有無(wú)參的構(gòu)造函數(shù)
@IdClass
注解復(fù)合主鍵的類(lèi),復(fù)合主鍵類(lèi)必須滿(mǎn)足:
- 實(shí)現(xiàn)Serializable接口;
- 有默認(rèn)的public無(wú)參數(shù)的構(gòu)造方法;
- 重寫(xiě)equals和hashCode方法。
@Embedded + @AttributeOverride
- @Embedded:注釋屬性的,表示該屬性的類(lèi)是嵌入類(lèi)。
- @AttributeOverrides:里面只包含了@AttributeOverride類(lèi)型數(shù)組。
- @AttributeOverride:包含要覆蓋的@Embeddable類(lèi)中字段名name和新增的@Column字段的屬性。
實(shí)體間關(guān)聯(lián)關(guān)系
@OneToOne
實(shí)體間一對(duì)一的關(guān)系。
- fetch:立即加載和延遲加載
- cascade:當(dāng)前類(lèi)對(duì)象操作了之后,級(jí)聯(lián)對(duì)象的操作。
REMOVE:級(jí)聯(lián)刪除操作。刪除當(dāng)前實(shí)體時(shí),與它有映射關(guān)系的實(shí)體也會(huì)跟著被刪除。
MERGE:級(jí)聯(lián)更新(合并)操作。當(dāng)前對(duì)象中的數(shù)據(jù)改變,會(huì)相應(yīng)地更新級(jí)聯(lián)對(duì)象中的數(shù)據(jù)。
DETACH:級(jí)聯(lián)脫管/游離操作。如果要?jiǎng)h除一個(gè)實(shí)體,但是它有外鍵無(wú)法刪除,你就需要這個(gè)級(jí)聯(lián)權(quán)限了。它會(huì)撤銷(xiāo)所有相關(guān)的外鍵關(guān)聯(lián)。
REFRESH:級(jí)聯(lián)刷新操作。更新數(shù)據(jù)前先刷新對(duì)象和級(jí)聯(lián)對(duì)象,再更新。
PERSIST:級(jí)聯(lián)持久化(保存)操作。持久保存擁有方實(shí)體時(shí),也會(huì)持久保存該實(shí)體的所有相關(guān)數(shù)據(jù)。
ALL,當(dāng)前類(lèi)增刪改查改變之后,關(guān)聯(lián)類(lèi)跟著增刪改查,擁有以上所有級(jí)聯(lián)操作權(quán)
- mappedBy:擁有關(guān)聯(lián)關(guān)系的域,如果關(guān)系是單向的就不需要,雙向關(guān)系表,那么擁有關(guān)系的這一方有建立、解除和更新與另一方關(guān)系的能力,而另一方?jīng)]有,只能被動(dòng)管理,這 個(gè)屬性被定義在關(guān)系的被擁有方。
- orphanRemoval:如果設(shè)置為true,當(dāng)關(guān)系被斷開(kāi)時(shí),多方實(shí)體將被刪除。否則會(huì)將對(duì)象的引用置為null。
- targetEntity:表示該屬性關(guān)聯(lián)的實(shí)體類(lèi)型。該屬性通常不必指定,ORM 框架根據(jù)屬性類(lèi)型自動(dòng)判斷。
一對(duì)一關(guān)系的例子
people 表(id,name,sex,birthday,address_id) address 表(id,phone,zipcode,address)
People和Address是一對(duì)一的關(guān)系。
方式一:通過(guò)外鍵的方式(一個(gè)實(shí)體通過(guò)外鍵關(guān)聯(lián)到另一個(gè)實(shí)體的主鍵)
@JoinColum:保存表與表之間關(guān)系的字段,它要標(biāo)注在實(shí)體屬性上。一般修飾在主控方,用來(lái)定義一對(duì)一,一對(duì)多等關(guān)系列。
關(guān)聯(lián)的實(shí)體的主鍵一般是用來(lái)做外鍵的。但如果此時(shí)不想主鍵作為外鍵,則需要設(shè)置referencedColumnName屬性。
方式二:通過(guò)關(guān)聯(lián)表的方式來(lái)保存一對(duì)一的關(guān)系。
關(guān)聯(lián)表:people_address (people_id,address_id)
@JoinTable:用于構(gòu)建一對(duì)多,多對(duì)多時(shí)的連接表,默認(rèn)會(huì)以主控表加下劃線(xiàn)加反轉(zhuǎn)表為表名。
- JoinColumns:該屬性值可接受多個(gè)@JoinColumn,用于配置連接表中外鍵列的信息,這些外鍵列參照當(dāng)前實(shí)體對(duì)應(yīng)表的主鍵列。
- inverseJoinColumns:該屬性值可接受多個(gè)@JoinColumn,用于配置連接表中外鍵列的信息,這些外鍵列參照當(dāng)前實(shí)體的關(guān)聯(lián)實(shí)體對(duì)應(yīng)表的主鍵列。
@OneToMany和@ManyToOne
注解一對(duì)多和多對(duì)一關(guān)系。
- JPA使用@OneToMany和@ManyToOne來(lái)標(biāo)識(shí)一對(duì)多的雙向關(guān)聯(lián)。一端(One)使用@OneToMany,多端(Many)使用@ManyToOne。
- 在JPA規(guī)范中,一對(duì)多的雙向關(guān)系由多端(Many)來(lái)維護(hù)。就是說(shuō)多端(Many)為關(guān)系維護(hù)端,負(fù)責(zé)關(guān)系的增刪改查。一端(One)則為關(guān)系被維護(hù)端,不能維護(hù)關(guān)系。
- 一端(One)使用@OneToMany注釋的mappedBy屬性表明是關(guān)系被維護(hù)端。
- 多端(Many)使用@ManyToOne和@JoinColumn來(lái)注釋屬性,@ManyToOne表明是多端,@JoinColumn設(shè)置在表中的關(guān)聯(lián)字段(外鍵)。
例子
- 文章表 article (id,title,content,author_id)
- 作者表 author (id,name)
@ManyToMany
注解多對(duì)多的關(guān)系。
角色和權(quán)限是多對(duì)多的關(guān)系。一個(gè)角色可以有多個(gè)權(quán)限,一個(gè)權(quán)限也可以被很多角色擁有。
JPA中使用@ManyToMany來(lái)注解多對(duì)多的關(guān)系,由一個(gè)關(guān)聯(lián)表來(lái)維護(hù)。這個(gè)關(guān)聯(lián)表的表名默認(rèn)是:主表名+下劃線(xiàn)+從表名。
這個(gè)關(guān)聯(lián)表只有兩個(gè)外鍵字段,分別指向主表ID和從表ID。字段的名稱(chēng)默認(rèn)為:主表名+下劃線(xiàn)+主表中的主鍵列名,從表名+下劃線(xiàn)+從表中的主鍵列名。
例子
權(quán)限表 user_permission(id,permission_name)
角色表 user_role(id,department_id, create_time, description, name, update_time)
關(guān)聯(lián)表 user_role_permission 表(role_id, permission_id)
注意
多對(duì)多關(guān)系中一般不設(shè)置級(jí)聯(lián)保存、級(jí)聯(lián)刪除、級(jí)聯(lián)更新等操作。
本例中,由于加了@JoinTable注解,關(guān)聯(lián)關(guān)系表會(huì)按照注解指定的生成。否則去掉注解,指定Role為關(guān)系維護(hù)端,所以生成的關(guān)聯(lián)表名稱(chēng)為:user_role_permission,關(guān)聯(lián)表的字段為:role_id 和permission_id。
小結(jié)
以上就是 JPA 實(shí)體類(lèi)中的注解介紹,文中的例子僅僅淺嘗輒止,希望大家可以實(shí)際應(yīng)用一下,后續(xù)我也會(huì)更深入的講解一些 JPA 的高級(jí)用法。