Hibernate ORM 版本 6.2.0.Final
即将发布,以下文章将尝试解释该版本中新增的一个新特性。
结构映射
现在可以通过使用 @Struct(name = "…")
注解可嵌入类型或 @Embedded
字段/属性来将可嵌入类型映射到命名 SQL 对象类型,也称为结构化类型。
hbm2ddl 架构生成工具支持生成 DDL 来创建和删除这些结构化类型。由于结构化类型属性顺序很重要,并且必须符合 Hibernate 的期望,因此用户可以在架构验证添加对结构化类型支持之前比较类型定义。
考虑以下简单的映射示例
@Embeddable
@Struct(name = "my_point")
public class Point {
private int x;
private int y;
}
将产生一个类似于以下架构
create type my_point as (
x int not null,
y int not null
)
可以通过在持久化属性上应用 @Column
来细化结构化列的名称和可空性。
@Entity
public class PointHolder {
@Id
private int id;
@Column(name = "the_point", nullable = false)
private Point p;
}
这将产生类似于以下架构
create table PointHolder as (
id int not null primary key,
the_point my_point not null
)
由于结构化类型属性的顺序至关重要,因此了解如何控制 Hibernate 的期望非常重要。有两种基本方法可以控制顺序
-
在
@Struct
注解中指定attributes
成员以定义顺序 -
使用Java记录通过规范构造函数隐式指定顺序
第一种方法很简单。如果所需的顺序是(y,x)
,则Point
嵌入类型需要通过使用@Struct(name = "my_point", attributes = {"y", "x"})
来声明这一点。
第二种方法更有趣,因为它利用了Hibernate 6.2中引入的另一个新特性,即对Java记录的原生支持。
@Embeddable
@Struct(name = "my_point")
public record Point(int y, int x) {}
对于Java记录,不再需要@EmbeddableInstantiator
,因为Hibernate现在根据规范构造函数自动配置合适的实例化器。规范构造函数中记录组件的顺序也代表了Hibernate期望结构化类型属性定义的顺序。
截至写作时,结构化类型支持仅实现于Oracle、PostgreSQL和DB2。 |
XML和JSON映射
由于XML和JSON是预定义的无结构类型,因此无需定义类型名或属性顺序。将嵌入类型映射为XML或JSON可以通过分别用@JdbcTypeCode(SqlTypes.SQLXML)
或@JdbcTypeCode(SqlTypes.JSON)
注解@Embedded
字段/属性来实现。
截至写作时,尚无数据库方言实现XML支持,所以以下将仅关注JSON部分,但未来将以相同方式应用于XML支持。 |
@Entity
public class JsonHolder {
@Id
private int id;
@JdbcTypeCode(SqlTypes.JSON)
@Column(name = "my_json", nullable = false)
private Point point;
}
具有此类映射的实体将大致产生以下架构
create table JsonHolder as (
id int not null primary key,
my_json json not null,
check (json_value(my_json, '$.x') is not null and json_value(my_json, '$.y') is not null)
)
如您所见,表定义包含一个检查约束,该约束通过访问json_value
函数来强制嵌入类型在JSON值内的约束。
使用嵌入类型属性进行HQL查询
select j.point.x, j.point.y
from JsonHolder j
将解析为相应的json_value
表达式
select json_value(j.point, '$.x'), json_value(j.point, '$.y')
from JsonHolder j
同样,赋值表达式将更新JSON文档的相关部分。
截至写作时,JSON支持仅实现于Oracle和PostgreSQL。 |