Hibernate 中的 @Struct 註解類型 – 結構化使用者定義類型
1. 概述
在本教程中,我們將回顧 Hibernate 的@Struct
註釋,它允許開發人員建立結構化的使用者定義類型。
SQL:1999 標準中引入了對結構化使用者定義類型(又稱為結構化類型)的支持,這是物件關係 (ORM) 資料庫的功能。
結構化或複合類型有其用例,特別是在 SQL:2016 標準中引入了對 JSON 的支援之後。這些結構化類型的值提供對其子部分的訪問,並且沒有像表中的行那樣的標識符或主鍵。
2. 結構映射
Hibernate 允許您透過@Struct
註釋類型為使用@Embeddable
註釋或@Embedded
屬性註釋的類別指定結構化類型。
2.1. @Struct
用於映射結構化類型
考慮下面的Department
類別範例,該類別具有@Embedded
Manager
類別(結構化類型):
@Entity
public class Department {
@Id
@GeneratedValue
private Integer id;
@Column
private String departmentName;
@Embedded
private Manager manager;
}
使用@Struct
註解定義的Manager
類別如下:
@Embeddable
@Struct(name = "Department_Manager_Type", attributes = {"firstName", "lastName", "qualification"})
public class Manager {
private String firstName;
private String lastName;
private String qualification;
}
2.2. @Embeddable
和@Struct
註解之間的區別
以@Struct
註解的類別將該類別對應到資料庫中的結構化使用者定義類型。例如,如果沒有@Struct
註釋, @Embedded
Manager
物件儘管是一個單獨的類型,但仍將成為Department
表的一部分,如下面的 DDL 所示:
CREATE TABLE DEPRARTMENT (
Id BIGINT,
DepartmentName VARCHAR,
FirstName VARCHAR,
LastName VARCHAR,
Qualification VARCHAR
);
帶有@Struct
註釋的Manager
類別將產生類似於以下內容的使用者定義類型:
create type Department_Manager_Type as (
firstName VARCHAR,
lastName VARCHAR,
qualification VARCHAR
)
加入@Struct
註解後, Department
物件如下DDL所示:
CREATE TABLE DEPRARTMENT (
Id BIGINT,
DepartmentName VARCHAR,
Manager Department_Manager_Type
);
2.3. @Struct
註解與屬性順序
由於結構化類型具有多個屬性,因此屬性的順序對於將資料對應到正確的屬性非常重要。定義屬性順序的一種方法是透過@Struct
註釋的「attributes」欄位。
在上面的Manager
類別中,您可以看到@Struct
註釋的「attributes」字段,它指定 Hibernate 期望Manager
屬性的順序(在序列化和反序列化時)為「firstName」、「lastName」和終於「資格」了。
定義屬性順序的第二種方法是使用 Java 記錄透過規範建構函數隱式指定順序,例如:
@Embeddable
@Struct(name = "Department_Manager")
public record Manager(String lastName, String firstName, String qualification) {}
在上面, Manager
記錄屬性將具有以下順序:「lastName」、「firstName」和「qualification」。
3.JSON映射
由於 JSON 是預先定義的非結構化類型,因此無需定義類型名稱或屬性順序。將@Embeddable
對應為 JSON 可以透過使用@JdbcTypeCode(SqlTypes.JSON)
註解嵌入欄位/屬性來完成。
例如,下面的類別包含一個Manager
對象,它也是 JSON 非結構化類型:
@Entity
public class Department_JsonHolder {
@Id
@GeneratedValue
private int id;
@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "department_manager_json")
private Manager manager;
}
以下是上述類別的預期 DDL 程式碼:
create table Department_JsonHolder as (
id int not null primary key,
department_manager_json json
)
以下是從department_manager_json
欄位中選擇屬性的範例 HQL 查詢:
select djh.manager.firstName, djh.manager.lastName, djh.manager.qualifications
from department_jsonholder djh
4。結論
@Embeddable
和@Embeddable @Struct
之間的區別在於後者實際上是底層資料庫中的使用者定義類型。雖然許多資料庫支援使用者定義類型,但支援@Struct
註解的 hibernate 方言有:
- 甲骨文
- 資料庫2
- PostgreSQL
在本文中,我們討論了 Hibernate 的@Struct
註解、如何使用它以及何時將其添加到域類別。
本文的源代碼可在 GitHub 上取得。