如何使用数据库列将JPA实体格式化为JSON?

时间:2014-11-08 23:35:35

标签: java jpa

将JPA实体转换为不包含相关对象但数据库列的JSON的最佳方法是什么。

考虑:

public class Question implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    private Integer id;

    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "question_title")
    private String questionTitle;

    @Size(max = 500)
    @Column(name = "question_desc")
    private String questionDesc;

    @JoinColumn(name = "requires_question_id", referencedColumnName = "id")
    @ManyToOne
    private Question requiredQuestion;

    ...
}

将问题直接转换为json可能如下所示:

{
    "id": 1,
    "questionTitle": "Q1",
    "questionDesc": "A Question 123"
    "requiredQuestion": {
        "id": 2, 
        "questionTitle": "Q2",
        "questionDesc": "A Question 456"
     } 
}

然而,更理想的结果可能如下所示:

{
    "id": 1,
    "question_title": "Q1",
    "question_desc": "A Question 123"
    "required_question_id": 2
}

获得理想结果的最佳方法是什么?

使用像“question_title”等字符串键创建一个hashmap并手动分配对象属性,然后将地图转换为json?

3 个答案:

答案 0 :(得分:1)

您可以使用Jackson JSON Processor将实体序列化为JSON,就像任何其他POJO一样。要完全控制输出格式,请为Question类编写custom serializer。它看起来像这样

public class QuestionSerializer extends JsonSerializer<Question> {
    @Override
    public void serialize(Question value, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeNumberField("id", value.getId());
        jgen.writeStringField("question_title", value.getQuestionTitle());
        jgen.writeStringField("question_desc", value.getQuestionDesc());
        jgen.writeNumberField("required_question_id", value.getRequiredQuestion().getId());
        jgen.writeEndObject();
    }
}

答案 1 :(得分:1)

在此类应用程序中,不应使用同一对象与客户端通信以及在数据库上保留数据。原因是您的表格结构可能会因需求或任何内容而发生变化,您必须更改JPA实体。此外,您还必须更改客户端的代码,因为JPA Entity类会更改其结构。

您应该创建DTO,这是一个简单的POJO,用于向客户端传输信息(序列化)并从客户端获取信息(反序列化)。并使用像Jackson或gson这样的库将Java对象转换为Json格式和逆向。

答案 2 :(得分:0)

手动为对象赋值不是一个好主意,因为你可以通过hibernate中的投影获得理想的结果然后你可以将地图转换为json

return sessionFactory.getCurrentSession()
.createCriteria(Question.class)
.createAlias("requiredQuestion","requiredQuestion")
.setProjection(Projections.projectionList()
    .add(Projections.property("id").as("id"))
    .add(Projections.property("questionTitle").as("questionTitle"))
    .add(Projections.property("questionDesc").as("questionDesc"))
    .add(Projections.property("requiredQuestion.id").as("requiredQuestionid")))
    .setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP)
.list();

这是获得您期望的结果的代码,您可以将其转换为json。