日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

函数指针使用场景和选择_在N + 1场景中使用@NamedEntityGraph更有选择地加载JPA实体...

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数指针使用场景和选择_在N + 1场景中使用@NamedEntityGraph更有选择地加载JPA实体... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

函數指針使用場景和選擇

N + 1問題是使用ORM解決方案時的常見問題。 當您將某些@OneToMany關系的fetchType設置為lazy時,就會發生這種情況,以便僅在訪問Set / List時才加載子實體。 假設我們有一個具有兩個關系的Customer實體:每個客戶的一組訂單和一組地址。

@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<OrderEntity> orders;@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<AddressEntity> addresses;

要加載所有客戶,我們可以發出以下JPQL語句,然后加載每個客戶的所有訂單:

List<CustomerEntity> resultList = entityManager.createQuery("SELECT c FROM CustomerEntity AS c", CustomerEntity.class).getResultList(); for(CustomerEntity customerEntity : resultList) {Set<OrderEntity> orders = customerEntity.getOrders();for(OrderEntity orderEntity : orders) {...} }

Hibernate 4.3.5(與JBoss AS Wildfly 8.1.0CR2一起提供)將從數據庫中僅為兩個(!)客戶生成以下一系列SQL語句:

Hibernate: selectcustomeren0_.id as id1_1_,customeren0_.name as name2_1_,customeren0_.numberOfPurchases as numberOf3_1_ fromCustomerEntity customeren0_ Hibernate: selectorders0_.CUSTOMER_ID as CUSTOMER4_1_0_,orders0_.id as id1_2_0_,orders0_.id as id1_2_1_,orders0_.campaignId as campaign2_2_1_,orders0_.CUSTOMER_ID as CUSTOMER4_2_1_,orders0_.timestamp as timestam3_2_1_ fromOrderEntity orders0_ whereorders0_.CUSTOMER_ID=? Hibernate: selectorders0_.CUSTOMER_ID as CUSTOMER4_1_0_,orders0_.id as id1_2_0_,orders0_.id as id1_2_1_,orders0_.campaignId as campaign2_2_1_,orders0_.CUSTOMER_ID as CUSTOMER4_2_1_,orders0_.timestamp as timestam3_2_1_ fromOrderEntity orders0_ whereorders0_.CUSTOMER_ID=?

如我們所見,第一個查詢從表CustomerEntity中選擇所有客戶。 接下來的兩個選擇先提取,然后在第一個查詢中加載我們已加載的每個客戶的訂單。 當我們有100個客戶而不是2個客戶時,我們將獲得101個查詢。 一個初始查詢可加載所有客戶,然后針對100個客戶中的每個客戶,另外查詢一個訂單。 這就是為什么將此問題稱為N + 1的原因。

解決此問題的常見習慣是強制ORM生成內部聯接查詢。 在JPQL中,這可以通過使用JOIN FETCH子句來完成,如以下代碼片段所示:

entityManager.createQuery("SELECT c FROM CustomerEntity AS c JOIN FETCH c.orders AS o", CustomerEntity.class).getResultList();

正如預期的那樣,ORM現在使用OrderEntity表生成一個內部聯接,因此只需要一個SQL語句即可加載所有數據:

selectcustomeren0_.id as id1_0_0_,orders1_.id as id1_1_1_,customeren0_.name as name2_0_0_,orders1_.campaignId as campaign2_1_1_,orders1_.CUSTOMER_ID as CUSTOMER4_1_1_,orders1_.timestamp as timestam3_1_1_,orders1_.CUSTOMER_ID as CUSTOMER4_0_0__,orders1_.id as id1_1_0__ fromCustomerEntity customeren0_ inner joinOrderEntity orders1_on customeren0_.id=orders1_.CUSTOMER_ID

在您知道必須為每個客戶加載所有訂單的情況下,JOIN FETCH子句將SQL語句的數量從N + 1減少到1。這當然具有缺點,即您現在要轉移一個訂單的所有訂單。客戶一次又一次的客戶數據(由于查詢中的其他客戶列)。

JPA規范從版本2.1引入,即所謂的NamedEntityGraphs。 通過此批注,您可以描述JPQL查詢應加載的圖形,而不是JOIN FETCH子句可以執行的圖形,從而為N + 1問題提供了另一種解決方案。 下面的示例演示了我們的客戶實體的NamedEntityGraph,該實體應該僅加載客戶名稱及其訂單。 訂單在子圖ordersGraph中有更詳細的描述。 在這里,我們看到我們只想加載訂單的字段ID和CampaignId。

@NamedEntityGraph(name = "CustomersWithOrderId",attributeNodes = {@NamedAttributeNode(value = "name"),@NamedAttributeNode(value = "orders", subgraph = "ordersGraph")},subgraphs = {@NamedSubgraph(name = "ordersGraph",attributeNodes = {@NamedAttributeNode(value = "id"),@NamedAttributeNode(value = "campaignId")})} )

在通過NameManager通過EntityManager加載JPQL查詢后,將其命名為JPQL查詢的提示:

EntityGraph entityGraph = entityManager.getEntityGraph("CustomersWithOrderId"); entityManager.createQuery("SELECT c FROM CustomerEntity AS c", CustomerEntity.class).setHint("javax.persistence.fetchgraph", entityGraph).getResultList();

Hibernate從版本4.3.0.CR1開始支持@NamedEntityGraph批注,并為上面顯示的JPQL查詢創建以下SQL語句:

Hibernate: selectcustomeren0_.id as id1_1_0_,orders1_.id as id1_2_1_,customeren0_.name as name2_1_0_,customeren0_.numberOfPurchases as numberOf3_1_0_,orders1_.campaignId as campaign2_2_1_,orders1_.CUSTOMER_ID as CUSTOMER4_2_1_,orders1_.timestamp as timestam3_2_1_,orders1_.CUSTOMER_ID as CUSTOMER4_1_0__,orders1_.id as id1_2_0__ fromCustomerEntity customeren0_ left outer joinOrderEntity orders1_ on customeren0_.id=orders1_.CUSTOMER_ID

我們看到Hibernate不會發出N + 1查詢,而是@NamedEntityGraph注釋強制Hibernate為每個左外部聯接加載訂單。 當然,這與FETCH JOIN子句有微妙的區別,在子句中,Hibernate創建了內部聯接。 與FETCH JOIN子句相反,左外部聯接還將加載不存在訂單的客戶,在FETCH JOIN子句中,我們僅加載具有至少一個訂單的客戶。

有趣的是,Hibernate加載的負載比表CustomerEntity和OrderEntity的指定屬性更多。 由于這與@NamedEntityGraph的規范(第3.7.4節)相沖突,因此我為此創建了一個JIRA問題 。

結論

我們已經看到,在JPA 2.1中,我們為N + 1問題提供了兩種解決方案:我們可以使用FETCH JOIN子句來急切地獲取一個@OneToMany關系,這將導致一個內部聯接,或者我們可以使用@NamedEntityGraph功能使我們通過左外部聯接指定要加載的@OneToMany關系。

翻譯自: https://www.javacodegeeks.com/2014/07/using-namedentitygraph-to-load-jpa-entities-more-selectively-in-n1-scenarios.html

函數指針使用場景和選擇

總結

以上是生活随笔為你收集整理的函数指针使用场景和选择_在N + 1场景中使用@NamedEntityGraph更有选择地加载JPA实体...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久精品国产99久久久 | 美女激情av | 桃色成人 | 91精品国产电影 | 日韩精品一区二区三区不卡 | 国产美女免费无遮挡 | 欧美人与禽zozzo性之恋的特点 | 亚洲免费高清视频 | 亚洲素人 | 男男车车的车车网站w98免费 | 国产成人精品一区二区三区网站观看 | 中文字幕视频网 | 日本一二三不卡视频 | 深夜福利网址 | 污免费在线观看 | 西西44rtwww国产精品 | 国产精品视频观看 | 韩国女同性做爰三级 | 噜噜噜视频| 国产精品自偷自拍 | 青青草日本| 国产视频一二三 | 蜜桃成熟时李丽珍国语 | 男生尿隔着内裤呲出来视频 | 国内国产精品天干天干 | 肌肉猛男裸体gay网站免费 | 日本69av| 草草福利视频 | 超碰97免费 | 麻豆高清视频 | 久久精品视频中文字幕 | 一级成人av | 亚洲精品66 | 国产顶级毛片 | 综合网久久 | 精品蜜桃一区二区三区 | 中文字幕第28页 | 91尤物在线| 日韩电影中文字幕 | 日本美女视频网站 | 日本大乳美女 | 亚洲欧美日韩精品在线 | 国产成人精品影院 | 成人午夜在线免费观看 | 国产a视频 | 韩日欧美 | 欧美最黄视频 | 欧美视频精品在线 | 牛牛av| 国产乱码精品一区二三赶尸艳谈 | 久久av免费 | 欧美色啪 | 动漫美女被吸奶 | 中国一级黄色大片 | 超碰免费公开在线 | 伊人综合影院 | 一区二区三区国产视频 | 快播久久 | 欧美特黄色片 | 亚州av影院| www.蜜桃av.com| 97天天操 | 中文av一区二区 | 久久免费视频精品 | 一区二区乱子伦在线播放 | 中文字幕在线免费观看视频 | 一起草av在线 | 清纯唯美亚洲综合 | 日韩一级 | 538国产视频 | 桃色一区二区三区 | 人操人操 | 国产v在线 | 男人的天堂aa | 欧美性生交大片免费看app麻豆 | 日韩高清网站 | 在线视频免费播放 | 中国性猛交 | 性爱视频日本 | 久久人妻少妇嫩草av无码专区 | 日韩久久久久久久 | 岛国av网址| 久久婷婷综合色丁香五月 | 伊人狼人综合 | 日韩欧美精品在线视频 | 国产欧美一区二区三区在线看 | 成人在线免费 | 天堂在线观看免费视频 | 日本黄色片. | 一区二区日韩电影 | 日本少妇xx| 色人天堂 | 午夜羞羞羞 | 蜜桃臀av一区二区三区 | 国产毛片3| 国产成人综合欧美精品久久 | 精品福利一区 | 久久久资源网 | 国产日韩欧美视频在线 |