簡體   English   中英

將JPA(Hibernate)中的本機(聯接)查詢轉換為JSON

[英]Convert native (join) queries in jpa (Hibernate) to json

我正在開發一個Spring Boot項目,並且正在使用jpa進行數據持久化。 現在,我有兩個相互關聯的表:用戶和項目。 一個用戶可以擁有任意數量的項目,而一個項目只能由一個用戶擁有。
這是我的pojos:
用戶

@Entity
@Table(name="users", uniqueConstraints = {
            @UniqueConstraint(columnNames = {
                "email"
            })
    })
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true)
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    @NaturalId
    @Column(unique = true)
    private String email;

    @NotBlank
    @JsonIgnore
    private String password;

    @NotBlank
    private String first_name;

    @NotBlank
    private String last_name;

    @OneToMany(cascade = CascadeType.REMOVE, orphanRemoval = true)
    @JsonIgnore
    private Set<Item> items;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "user_roles",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles = new HashSet<>();


    @Column(nullable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    private Date createdAt;

    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    private Date updatedAt;

項目

@Entity
@Table(name="items")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true)
public class Item {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    @NotNull
    private String name;

    private String description;

    @NotNull 
    private Date purchase_date;

    private double price;

    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(name = "owner", nullable = true)
    private User owner;

    @Column(nullable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    private Date createdAt;

    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    private Date updatedAt;

現在,我想將所有項目都獲取為RESTfull JSON。 我需要為用戶添加項目,以便獲得以下JSON:

{
    "item_id":1,
    "name":"item1",
    "price":120.00,

    etc .....

    "owner_id":1,
    "owner_name":"Jon"
    etc ....

}

所以我正在使用自定義的本機查詢

SELECT i.id, i.name, i.description ...... u.id, u.name ..... from items i , users u where i.owner = u.id

然后我返回query.getResultList()但是這返回的是字符串數組,而不是像這樣的json

[

    [ 1 , "item1" , 120.00 , ..... , 1 , "Jon" , ....]
    [ 2 , "item2" , 420.00 ....   ]
etc...
]

如何將返回的對象直接轉換為JSON或映射到將列名映射到值的映射列表,然后將其轉換為JSON?

您可以使用構造函數表達式創建一個包含所需數據的DTO(數據傳輸對象)。

package dto;

public class ItemDTO {

   private final Long item_id;
   private final String name;
   private final Long owner_id;
   private final String owner_name;

   public ItemDTO(Long item_id, String name, Long owner_id, String owner_name) {
      // set the fields
   }

   // getters
}

然后在構造函數表達式查詢中使用此DTO(重要說明:這僅適用於JPQL查詢而不適用於本機查詢)

SELECT new dto.ItemDTO(i.id, i.name, i.owner.id, i.owner.name) from Item i where i.owner.id = u.id

此DTO可用於序列化為JSON。

在此處閱讀有關構造函數表達式的更多信息: https : //vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/

您可以使用它,不需要在每個請求上都使用新的DTO。

@SuppressWarnings("unchecked")
public static List<ObjectNode> getQueryResult(EntityManager entityManager, String nativeQuery, Object... parameters) {

    Query localQuery = entityManager.createNativeQuery(nativeQuery,Tuple.class);

    for(int i = 0; i < parameters.length; i++)
        localQuery.setParameter(i+1, parameters[i]);

    return toJson(localQuery.getResultList());
}

private static List<ObjectNode> toJson(List<Tuple> results) {

    List<ObjectNode> json = new ArrayList<>();

    ObjectMapper mapper = new ObjectMapper();

    for (Tuple tuple : results)
    {
        List<TupleElement<?>> cols = tuple.getElements();

        ObjectNode node = mapper.createObjectNode();

        for (TupleElement col : cols)
            node.put(col.getAlias(), tuple.get(col.getAlias()).toString());

        json.add(node);
    }
    return json;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM