使用Spring Data持久化JSON


基本上每个现代数据库系统都有自己的数据类型来持久化 JSON。使用这种类型至少可以确保正确的格式 - 大多数情况下还有其他优点,例如更快的 I/O。
作为 Spring Boot 开发人员,我们希望在不手动处理 Java 实体和数据库之间的映射的情况下访问 JSON 字段。在最好的情况下,我们只使用代表 JSON 的 Java 类——与 Jackson 和 Hibernate 的映射是透明地发生的。

技术背景
Spring Data / Hibernate不支持开箱即用的 JSON 字段,但有一个库为最常见的数据库系统提供自定义类型:hibernate-types。这是一个很棒的开源库,请多多支持!
假设我们想要扩展我们的微服务示例并向表中添加一个PartDetails字段CarPart。JSON 应具有以下结构。

{
    "countryCode": "DE",
   
"dimensions": {
       
"width": 1500,
       
"height": 744,
       
"depth": 45
    },
   
"weight": 3200
}

首先,我们将所需的依赖项添加到我们的pom.xml. 我们在最初的示例中使用 Maven - Gradle 也不例外。

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>2.16.2</version>
</dependency>

接下来我们需要代表我们的 JSON 的模型类。它们还包含一些验证约束——这是可选的,但在持久化之前确保它是一件好事。

public class PartDetails {

    @NotNull
    @Size(max = 2)
    private String countryCode;

    @Valid
    private PartDetailsDimensions dimensions;

    private Long weight;

}

public class PartDetailsDimensions {

    @NotNull
    private Long width;

    @NotNull
    private Long height;

    @NotNull
    private Long depth;

}

我们可以通过以下方式扩展我们的CarPart实体。

@Entity
@TypeDefs({
    @TypeDef(name = "json", typeClass = JsonStringType.class)
})
public class CarPart {

   
// ...

    @Column(columnDefinition =
"json")
    @Type(type =
"json")
    private PartDetails partDetails;

}

一个自定义的类型定义 @TypeDef(name = "json", ...) 被注册在该类中,通过用 @Type(type = "json") 注释它,该类对该字段变得活跃。在我们的案例中(MySQL),类JsonStringType接管了PartDetails到JSON的转换。columnDefinition的值必须是 "json"。

现在我们可以在我们的代码中直接使用模型类了!
JSON是由自定义类型持久化的,在后台使用ObjectMapper。