如何使用 Hibernate / Spring boot 在 mysql 中将 JSON 文件存储为 JSON 数据类型?

Ank*_*rma 5 java mysql json hibernate spring-boot

我尝试了多种将 json 文件存储在数据库中的方法,但最终为每个条目创建了不同的列。

我想将它存储为单个列中的“json”类型。是否可以?

我的json文件。

用户.json

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
...
]
Run Code Online (Sandbox Code Playgroud)

这是一个 spring-boot 应用程序,我有相关的控制器和服务。

在我的域包中。(地址和公司是可嵌入的类)

用户.java

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
...
]
Run Code Online (Sandbox Code Playgroud)

主文件(存储在数据库中)

TypeReference 和 ObjectMapper 来自 Jackson

@Data
@AllArgsConstructor @NoArgsConstructor
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String username;
    private String email;
    private String phone;
    private String website;

    @Embedded
    private Address address;

    @Embedded
    private Company company;
}
Run Code Online (Sandbox Code Playgroud)

在 mysql 中,它为 id, name, username, ...

我想将它作为使用弹簧靴的类型存储在单列中json

Smi*_*ile 4

您的代码将 json 读入对象列表User并保存到数据库。您需要编写一些自定义逻辑将其保存为 json。有多种方法可以做到这一点。

你可以做类似的事情

User1)在类中添加另一个变量private String jsonData

2)@PrePersist方法中,编写序列化逻辑

3) 用@JsonInclude()- 标记其他属性以包含在 Jackson 中 @Transient- 在单独的列中忽略持久性。您可能不想将这些注释添加到id属性中,因为每个 json 对象都将根据数据库中的特定 id 进行存储。

所以,新属性会是这样的

@NonNull
@Column(columnDefinition = "JSON") // Only if Database has JSON type else this line can be removed
private String jsonData;
Run Code Online (Sandbox Code Playgroud)

预坚持:

@PrePersist
public void prePersist() {
    try {
        this.setJsonData(new ObjectMapper().writeValueAsString(this));
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑: 您可能会面临方法@Transient中属性为空的问题@PrePersist。在这种情况下,您可以使用 setter 方法。但是每次在保存调用之前更改任何属性时,您都必须调用此设置器。

public void setJsonData(String jsonData) {
    // Method parameter jsonData is simply ignored
    try {
        this.jsonData = new ObjectMapper().writeValueAsString(this);
    } catch (JsonProcessingException e) {
        log.error(e.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)