Java 如何使用Springboot和Hibernate映射DTO和Aggentity类中的Postgres JSON数据类型
我的课堂反应如下:Java 如何使用Springboot和Hibernate映射DTO和Aggentity类中的Postgres JSON数据类型,java,json,hibernate,spring-boot,spring-mvc,Java,Json,Hibernate,Spring Boot,Spring Mvc,我的课堂反应如下: public static class HealthGoalsHighlight { @ApiModelProperty(value = "Total number of eligible users") private Long totalEligibleUsers; @ApiModelProperty(value = "Total number of registered users") private Long totalRegiste
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;
}
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)
);
本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)
);
现在,表格结构已更改为如下所示:
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;
}
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\u qualified\u users
,total\u registed\u users
,total\u users\u with\u goal
,top\u goal\u name
,bottom\u goal\u name
都将合并为一个JSON数据类型的单列健康指标值
如何为JSON数据类型列编写响应DTO。还有,在我的AggMapper类中需要做哪些更改。一种方法是使用converter函数。您可以使用converter函数获取相同格式的值
在列定义中更改orm.xml
如下内容
<basic name="healthGoalsMetricValue">
<column name="health_goals_metric_value" nullable="true"/>
<convert converter="path.to.your.HealthGoalsMetricValueConverter"/>
</basic>
你的类HealthGoalsMetricValue
看起来像
//////////////////注释后编辑的转换器类
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;
}
import com.fasterxml.jackson.core.JsonProcessingException;
导入com.fasterxml.jackson.databind.JsonNode;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入javax.persistence.AttributeConverter;
导入javax.persistence.Converter;
导入java.io.IOException;
@转换器
公共类HealthGoalsMetricValueConverter实现AttributeConverter{
私有最终ObjectMapper mapper=新ObjectMapper();
//然后像那样覆盖
@凌驾
公共字符串convertToDatabaseColumn(HealthGoalsHighlight healthGoalsMetricValue){
试试{
json=mapper.writeValueAsString(healthGoalsMetricValue);
}捕获(JsonProcessingException异常){
抛出新的JsonProcessingException(“对象序列化时出错”,异常);
}
返回json;
}
//然后再次覆盖
@凌驾
public Health GoalsMetricValue convertToEntityAttribute(字符串healthGoalsMetricValuestr){
HealthGoalsMetricValue HealthGoalsMetricValue=null;
试一试{
if(healthGoalsMetricValue!=null){
healthGoalsMetricValue=mapper.readValue(healthGoalsMetricValuestr,healthGoalsMetricValue.class);
}
}捕获(异常){
抛出新异常(“对象反序列化时出错”,异常);
}
返回healthGoalsMetricValue;
}
这一切都将为您完成任务。如果您可以添加额外的库来查看项目,这将非常简单
有了这个库,您将得到如下简单的代码
@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>
Vladmichalcea网站
hibernate-types-52
2.9.10//或更新版本
请共享现有AggMapper类的代码。convertToDatabaseColumn(HealthGoalsMetricValue HealthGoalsMetricValue)——在此方法中为“HealthGoalsMetricValue”我应该在哪里定义这个类以及它的内容。否则它会给我错误,无法解析symbol HealthGoalsMetricValue。这将是实体类中JSON克隆的类型。HealthGoalsHighlight
@sandeep@Sandeep如果还有任何疑问,请告诉我。我想我把一切都搞砸了。犯了很多错误。让我试试看这里是一步一步的。这是mu DTO的样子。公共类HealthGoalsHighlightResponseDto实现可序列化的{private MetadataTo metadata;private HealthGoalsHighlight HealthGoalsHighlight;@EqualsAndHashCode公共静态类HealthGoalsHighlight{@ApiModelProperty(value=“Total metrics”)私有映射healthGoalsMetricValue;}}}这是我的AggEntity类公共类HealthGoalsHighlightAggEntity扩展AggBaseEntity{@Convert(Convert=HealthGoalsMetricValueConverter.class)私有HealthGoalsHighlight HealthGoalsHighlight;}我没有使用Maven。我如何使用这个库。我需要下载并安装到我的项目中吗?如果需要,如何做。@sandeep只需将该部分添加到pom.xml中。然后将@TypeDefs
放在实体上,将@Type
放在字段上,您就可以开始了。请参阅这个很酷的文档