![](/img/trans.png)
[英]What is the best practice for JPA/Hibernate entity classes and synchronization?
[英]What is best practice for performing read only operations in JPA/Hibernate?
hibernate 手冊的第28.6節提到您不應該使用實體查詢進行只讀獲取,因為它們會因請求太多數據而受到影響。
這是有道理的,我們已經看到復雜的域模型會導致運行時間很長的查詢,尤其是在使用表視圖時。
該手冊繼續指出:
對於只讀事務,您應該獲取 DTO 預測,因為它們允許您訪問 select 與滿足特定業務用例所需的列一樣多。
但是 AFAIK JPA 並沒有提供獲取這些預測的好方法,您只能使用標准構建器,我們發現它冗長、脆弱並且經常無法正常工作(實施起來很困難)。
事實上,查看 SO 上的各種帖子表明,很多人正在使用實體進行讀取。 所以我提出的問題如下:
您必須了解沒有明確的答案,每個人都會根據他們的經驗給您不同的建議/建議。
通常,首選的解決方案是使用 DTO 方法,但如何實現該方法留給開發人員練習。 一些開發人員太懶了,或者只是接受/應對使用實體查詢可能產生的負面影響。 這實際上取決於您的用例和您的需求。
不過,我認為,您正在尋找的是像Blaze-Persistence Entity Views這樣的解決方案。
我創建了該庫,以允許在 JPA 模型和自定義接口或抽象 class 定義的模型之間輕松映射,例如 Spring Data Projections on steroids。 這個想法是您以您喜歡的方式定義您的目標結構(域模型),並通過 JPQL 表達式將 map 屬性(吸氣劑)定義為實體 model。
示例用例的 DTO model 使用 Blaze-Persistence Entity-Views 可能如下所示:
@EntityView(User.class)
public interface UserDto {
@IdMapping
Long getId();
String getName();
Set<RoleDto> getRoles();
@EntityView(Role.class)
interface RoleDto {
@IdMapping
Long getId();
String getName();
}
}
查詢是將實體視圖應用於查詢的問題,最簡單的就是通過 id 進行查詢。
UserDto a = entityViewManager.find(entityManager, UserDto.class, id);
Spring 數據集成允許您幾乎像 Spring 數據投影一樣使用它: https://persistence.blazebit.com/documentation/entity-view/manual-html/。
Page<UserDto> findAll(Pageable pageable);
最好的部分是,它只會獲取實際需要的 state
我見過很多人為關聯做 LAZY fetching,如果你不需要來自其他表的數據,這可以避免大連接,並且通常可以解決問題。 但是,每個查詢都不能覆蓋 fetch 策略,因此您不能選擇對某些查詢執行 LAZY fetching,然后為其他查詢執行 EAGER fetching。
DTO 預測確實是一個更好的選擇。 In pure JPA that requires messing with CriteriaBuilder.construct(....)
, but Spring JPA has a very nice wrapper for it: https://docs.spring.io/spring-data/jpa/docs/current/reference/ html/#projections
使用 DTO 投影,查詢中只會包含您需要的列和連接。
對於非常大的只讀操作,比如報告用例,最好不要使用 ORM 框架,而是使用一些專門的數據框架。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.