![](/img/trans.png)
[英]Mapping JPA or Hibernate projection query to DTO (Data Transfer Object)
[英]Pattern for JPA: Generating Data Transfer Object DTO from Entity and merging DTO to database
我正在尋找一種從JPA實體創建數據傳輸對象(DTO)的好方法,反之亦然。 我想將DTO作為JSON發送到客戶端,然后接收修改后的DTO並將其保存回數據庫。 在從JSON解析為Java類之后,從接收到的對象上的EntityManager執行合並方法將是最容易的。
例如,有以下Entity和Rest方法用於保存修改后的對象:
@Entity
@Table(name="CUSTOMER")
public class Customer {
@Id
Long id;
@Version
Long version;
String name;
String address;
String login;
String password;
String creditCardNumber;
@OneToMany(cascade = CascadeType.ALL)
List<Foo> fooList;
... Getter() and Setter()
}
private EntityManager em;
@POST
@Path("/saveCustomer")
public void saveCustomer ( Customer customer) {
em.merge(customer);
return;
}
只要我將整個實體類作為JSON發送並接收整個實體,這樣就可以正常工作。 然后,EntityManager將修改后的對象合並到數據庫中。 但是當我只想提供實體的一個子集(比如只有客戶的名稱和地址)時,會出現問題:
創建實體子集的最佳方法是什么?
- 手工編寫實體的DTO? 這將為實體的每個子集生成重復的代碼,必須對其進行維護。
如何將作為實體子集的DTO合並回數據庫?
- 使用EntityManager的merge()方法不起作用。 起初,DTO不是實體,因此無法合並。 只需從DTO創建實體,實體中就會有一些未設置的值。 合並后,數據庫中的值將為NULL。
我想出的一個想法是為我想要為實體指定的每個子集指定其他實體。 (就像數據庫視圖一樣)這將是重復的代碼,但它可以解決DTO與數據庫合並的問題。 (也許這段代碼可以自動生成)
例如,實體CustomerView1鏈接到與Customer類相同的表,但僅提供客戶的名稱和地址。 它是真正的Customer類的DTO,可以作為JSON發送並在服務器外部進行修改。 然后,該類也可以由EntityManager合並到數據庫。
@Entity
@Table(name="CUSTOMER")
public class CustomerView1 {
@Id
Long id;
@Version
Long version;
String name;
String address;
... Getter() and Setter()
}
但我對這個解決方案有疑問,我不知道這是否會破壞JPA對實體的緩存並可能導致一些問題。
我的問題是,是否有一種模式可以解決DTO的代碼重復並將DTO合並回數據庫?
或者是否有用於此目的的圖書館? - 某些東西,比如DTO的自動生成和將DTO復制回真實實體,以便可以將它們與EntityManager合並。
如果實體與DTO之間的大小差異不大,您可以選擇發送實體。
使用DTO時,要克服丟失更新等並發問題,必須將實體版本合並到DTO中。
如果您不使用實體版本,並且在REST GET和PUT方法之間更改了基礎行,您將覆蓋最終用戶並不真正意識到的更改。
每當我必須改變實體(創建,更新,刪除)時,我依賴於JPA和Hibernate樂觀鎖定機制 。
對於UI列表,表格,搜索結果DTO是可行的選項,因為您只對原始實體的投影感興趣。 這樣可以加快檢索速度,並且您可以從JPA不支持的其他SQL功能(窗口函數)中受益。
看一下直接解決問題的Value Object設計模式。
本教程對值對象進行了很好的介紹。
聽起來你正在描述的正是Blaze-Persistence Entity Views所做的。 當前版本僅支持創建讀取模型,即您要發送給客戶端的模型,但寫模型部分幾乎已完成。 實體視圖在接口/抽象類DTO表示和實體模型之間映射。 該庫充分利用映射信息來實現各種性能優化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.