2014-11-08 58 views
0

將JPA實體轉換爲不包含相關對象但數據庫列的JSON的最佳方式是什麼?如何將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?

回答

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(); 
    } 
} 
+0

何時需要任何建議問題爲空?編寫字符串字段時不能調用getId。簡單地說,if(value.getRequiredQuestion()!= null)在它之前? – javajaba 2014-11-09 21:00:15

+1

是的,你必須檢查null requiredQuestion,但是根據你想要輸出的情況(根本不需要'required_question_id'字段,或者null作爲值),你可以使用'jgen.writeNullField(「required_question_id」) '在'else'分支中。 – 2014-11-09 22:45:46

0

手動分配值的對象不是一個好主意,因爲你可以在休眠投影讓你期望的結果,然後你可以在地圖轉換成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。

1

在這種類型的應用程序中,您不應該使用相同的對象來與客戶端通信並在數據庫上保存數據。原因是你的表結構可能會因需求或其他原因而改變,你必須改變你的JPA實體。此外,您必須更改客戶端的代碼,因爲JPA實體類會更改其結構。

您應該創建DTO,這是一個簡單的POJO,用於向客戶端傳輸信息(序列化)並從客戶端獲取信息(反序列化)。並使用像Jackson或gson這樣的庫將Java對象轉換爲Json格式和反轉。