如何使用 Springboot 和 Hibernate 在 DTO 和 Aggentity 类中映射 Postgres JSON 数据类型
Posted
技术标签:
【中文标题】如何使用 Springboot 和 Hibernate 在 DTO 和 Aggentity 类中映射 Postgres JSON 数据类型【英文标题】:How to map Postgres JSON data type in DTO and Aggentity class using Springboot and Hibernate 【发布时间】:2020-09-14 07:19:09 【问题描述】:我有一个 ResponseDto 类,如下所示:
public static class HealthGoalsHighlight
@ApiModelProperty(value = "Total number of eligible users")
private Long totalEligibleUsers;
@ApiModelProperty(value = "Total number of registered users")
private Long totalRegisteredUsers;
@ApiModelProperty(value = "Total number of users with atleast one goal count")
private Long totalUsersWithGoal;
@ApiModelProperty(value = "Top goal name selected by user")
private String topGoal;
@ApiModelProperty(value = "Bottom goal name selected by user")
private String bottomGoal;
此 DTO 是根据下表结构制作的:
health_goals
(
uid BIGSERIAL NOT NULL CONSTRAINT health_goals_pkey primary key,
employer_key bigint not null,
total_eligible_users bigint not null,
total_registered_users bigint not null,
total_users_with_goal bigint not null,
top_goal_name varchar(255),
bottom_goal_name varchar(255),
created_ts TIMESTAMP NOT NULL DEFAULT NOW(),
updated_ts TIMESTAMP NOT NULL DEFAULT NOW(),
created_by varchar(255),
updated_by varchar(255)
);
现在表结构已更改为:
health_goals
(
uid BIGSERIAL NOT NULL CONSTRAINT health_goals_pkey primary key,
employer_key bigint not null,
health_goals_metric_value json null,
created_ts TIMESTAMP NOT NULL DEFAULT NOW(),
updated_ts TIMESTAMP NOT NULL DEFAULT NOW(),
created_by varchar(255),
updated_by varchar(255)
);
现在基本上所有这些列,如total_eligible_users
、total_registered_users
、total_users_with_goal
、top_goal_name
、bottom_goal_name
将被合并为单个列health_goals_metric_value
作为 JSON 数据类型。
如何为 JSON 数据类型列编写响应 DTO。另外,我的 AggMapper 类中需要进行哪些更改。
【问题讨论】:
请分享您现有的 AggMapper 类的代码。 【参考方案1】:一种方法是使用转换器功能。您可以使用转换器函数来获取相同格式的值。
在您的列定义中更改您的orm.xml
如下所示
<basic name="healthGoalsMetricValue">
<column name="health_goals_metric_value" nullable="true"/>
<convert converter="path.to.your.HealthGoalsMetricValueConverter"/>
</basic>
或者如果你有java文件
代理将有以下条目
@Convert(converter = HealthGoalsMetricValueConverter.class)
private HealthGoalsHighlight healthGoalsHighlight ;
你的班级 HealthGoalsMetricValue
看起来像
////////////////在cmets之后编辑转换器类
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.io.IOException;
@Converter
public class HealthGoalsMetricValueConverter implements AttributeConverter<HealthGoalsMetricValue, String>
private final ObjectMapper mapper = new ObjectMapper();
//And then override like that
@Override
public String convertToDatabaseColumn(HealthGoalsHighlight healthGoalsMetricValue)
try
json = mapper.writeValueAsString(healthGoalsMetricValue);
catch (JsonProcessingException exception)
throw new JsonProcessingException("Error occurred while object serialization", exception);
return json;
//And then override again
@Override
public HealthGoalsMetricValue convertToEntityAttribute(String healthGoalsMetricValuestr )
HealthGoalsMetricValue healthGoalsMetricValue = null;
try
if (healthGoalsMetricValue != null)
healthGoalsMetricValue = mapper.readValue(healthGoalsMetricValuestr, HealthGoalsMetricValue.class);
catch (Exception exception)
throw new Exception("Error occurred while object Deserialization", exception);
return healthGoalsMetricValue;
这一切都将为您完成工作。
【讨论】:
convertToDatabaseColumn(HealthGoalsMetricValue healthGoalsMetricValue) -- 在这个方法“HealthGoalsMetricValue”中,我应该在哪里定义这个类以及它的内容。否则它给我错误,无法解析符号 HealthGoalsMetricValue。 这将是实体类中 JSON cloumn 的类型。HealthGoalsHighlight
@sandeep
@Sandeep 如果仍有疑问,请告诉我。
我想我把一切都搞砸了。得到很多错误。让我试着一步一步写到这里。这就是 mu DTO 的样子。公共类 HealthGoalsHighlightResponseDto 实现 Serializable private MetadataDto 元数据;私人健康目标突出健康目标突出; @EqualsAndHashCode 公共静态类 HealthGoalsHighlight @ApiModelProperty(value = "Total metrics") private Map如果您可以添加其他库,请查看 https://github.com/vladmihalcea/hibernate-types 项目,这非常容易。
有了这个库,你最终会得到像这样简单的代码
@Entity
@Table(name = "health_goals")
@TypeDefs(
@TypeDef(name = "json", typeClass = JsonStringType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
)
public class HealthGoal
// all other columns
@Type(type = "json")
private HealthGoalsHighlight healthGoalsHighlight;
// getters setters
如果使用maven添加依赖
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.9.10</version> // or newer version
</dependency>
【讨论】:
我没有使用 Maven。我该如何使用这个库。我需要下载并安装在我的项目中吗?如果是,该怎么做。 @sandeep 只需将@TypeDefs
放在您的实体上,将@Type
放在字段上,您就可以开始了。看到这个很酷的文档vladmihalcea.com/…以上是关于如何使用 Springboot 和 Hibernate 在 DTO 和 Aggentity 类中映射 Postgres JSON 数据类型的主要内容,如果未能解决你的问题,请参考以下文章
手把手教你 Spring Boot 整合 Spring Data Jpa
如何使用 SpringBoot 和 Angular2 设置结构?