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
放在字段上,您就可以开始了。请参阅这个很酷的文档