簡體   English   中英

在 JPA/Hibernate 中執行只讀操作的最佳實踐是什么?

[英]What is best practice for performing read only operations in JPA/Hibernate?

hibernate 手冊的第28.6節提到您不應該使用實體查詢進行只讀獲取,因為它們會因請求太多數據而受到影響。

這是有道理的,我們已經看到復雜的域模型會導致運行時間很長的查詢,尤其是在使用表視圖時。

該手冊繼續指出:

對於只讀事務,您應該獲取 DTO 預測,因為它們允許您訪問 select 與滿足特定業務用例所需的列一樣多。

但是 AFAIK JPA 並沒有提供獲取這些預測的好方法,您只能使用標准構建器,我們發現它冗長、脆弱並且經常無法正常工作(實施起來很困難)。

事實上,查看 SO 上的各種帖子表明,很多人正在使用實體進行讀取。 所以我提出的問題如下:

  1. 正在避免在現實世界的企業應用程序中常見的只讀實體查詢,我覺得它不是。
  2. 如果是,人們使用什么工具來使這個可以忍受,一個單獨的查詢 dsl 浮現在腦海中,jOOQ?
  3. 是否有任何資源為與持久層連接的 Spring 應用程序的架構制定了最佳實踐(我正在考慮可能導致問題的其他復雜問題,例如事務管理),似乎每個人都接受一種特別的方法。

您必須了解沒有明確的答案,每個人都會根據他們的經驗給您不同的建議/建議。

通常,首選的解決方案是使用 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.

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