函数指针使用场景和选择_在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

函数指针使用场景和选择

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

东师计算机应用基础在线作业,东师《计算机应用基础》15春在线作业1答案

《计算机应用基础》15 春在线作业 1 单选题 多选题 判断题一、单选题(共 25 道试题&#xff0c;共 62.5 分。 )1. 21、 1946 年 2 月&#xff0c;在美国诞生了世界上第一台计算机&#xff0c;它的名字叫:A. EDVACB. EDSACC. ENIACD. UNIVAC-1----------------选择&#xff1a;C…

abb智能控制系统_ABB助力国网冀北电力打造虚拟电厂

近日&#xff0c;ABB为国网冀北电力有限公司定制了智能配电计量与协调控制解决方案&#xff0c;对其虚拟电厂进行远程电能管理&#xff0c;实现高峰调节和负载转移&#xff0c;提高电力系统效率&#xff0c;保持供电稳定性。虚拟电厂是通过分布式电力管理系统将电网中发电端(尤…

通过通用数据访问扩展AWS生态系统

Amazon Web Services&#xff08;AWS&#xff09;可帮助组织托管和管理其数据流程&#xff0c;例如构建数据可视化和执行ETL任务。 在CData&#xff0c;我们可以轻松地将AWS Services与异构业务应用程序和分布式数据存储连接起来&#xff0c;以最终帮助企业对其数据进行更全面的…

android官方文档中文版_Now in Android:01 - 如何掌握最新的 Android 技术?

每隔几天我都会通过 Android Developers 的油管官方频道&#xff0c;来了解一下最近 Android 发布了哪些有趣的新技术&#xff0c;最近发现官方推出了一个新的系列视频叫做&#xff1a;Now in Android&#xff0c;目前更新了 4 期&#xff0c;我觉得这个系列蛮有趣的&#xff0…

mvc路由 html,asp.net-mvc – ASP.NET MVC路由从html页面开始

我正在使用IIS 6.我想我的问题是我不知道如何使用routes.MapRoute路由到一个非控制器.我有一个url,如example.com,我希望它为index.htm页面提供服务,而不是使用MVC.我该如何设定&#xff1f;在IIS中,我将index.htm作为我的起始文档,我的global.asax具有标准的“默认”路由,其中…

c++ 反射_固体火箭发动机黏接壳体超声C扫描检测系统研制与应用

某固体火箭发动机燃烧室采用壳体/绝热层/包覆层/推进剂的多界面结构形式&#xff0c;其中绝热层采用玻璃纤维缠绕成型后与钢质旋压壳体胶接而成。在胶接过程中&#xff0c;若存在壳体内部多余物清理不干净、绝热层与壳体配合不严、胶层内部气体未排净等情况&#xff0c;黏接层易…

java scala_经过几天的Scala回归Java的10个最烦人的事情

java scala因此&#xff0c;我正在尝试使用Scala&#xff0c;因为我想编写一个解析器&#xff0c;而Scala Parsers API似乎非常合适。 毕竟&#xff0c;我可以在Scala中实现解析器并将其包装在Java接口后面&#xff0c;因此除了附加的运行时依赖关系之外&#xff0c;应该不存在…

常用计算机网络技术缩写词和术语,网络技术缩写词和术语

常用计算机网络技术缩写词和术语LAN&#xff1a;Local Area Network 局域网WAN: Wide Area Network 广域网MAN: Metropolitan Area Network 城域网FM: Frequency Modulation 频率调制AM: Amplitude Modulation 振幅调制PM: Phase Modulation 相位调制FSK: Frequency-shift Keyi…

python区域找图命令_python读取图片任意范围区域

使用python进行图片处理&#xff0c;现在需要读出图片的任意一块区域&#xff0c;并将其转化为一维数组&#xff0c;方便后续卷积操作的使用。 下面使用两种方法进行处理&#xff1a; convert 函数 from PIL import Image import numpy as np import matplotlib.pyplot as plt …

通用计算机系统的工作方式,通用计算机操作系统典型体系结构综述

摘要:随着操作系统应用领域的扩大&#xff0c;以及操作系统硬件平台的多样化&#xff0c;操作系统的体系结构和开发方式都在不断更新&#xff0c;目前通用机上常见操作系统的体系结构有如下几种:模块组合结构、层次结构、虚拟机结构和微内核结构。本文引用地址&#xff1a;http…

[MEGA DEAL] Ultimate SQL Bootcamp认证捆绑包(98%)

像Pro一样管理任务和数据库&#xff0c;提供有关SQL Lite&#xff0c;Microsoft SQL&#xff0c;MySQL&#xff0c;PostgreSQL&#xff0c;Rest API和Oracle SQL的6门课程 嘿&#xff0c;怪胎&#xff0c; 本周&#xff0c;在我们的JCG Deals商店 &#xff0c;我们提供了另一…

jersey spring_教程–带有Jersey和Spring的Java REST API设计和实现

jersey spring想要在Java中使用REST&#xff1f; 然后您来对地方了&#xff0c;因为在博客文章中&#xff0c;我将向您介绍如何“美丽”地设计REST API&#xff0c;以及如何使用Jersey框架在Java中实现它。 本教程中开发的RESTful API将演示针对存储在MySql数据库中的播客资源的…

html5 css svg,6款基于SVG的HTML5CSS3应用和动画

1、CSS3/SVG质感背景小图标 镂空效果图标按钮今天我们来分享一款用CSS3和SVG实现的质感背景小图标&#xff0c;鼠标滑过图标时出现镂空的效果&#xff0c;并且有质感背景的描边&#xff0c;效果非常不错。2、HTML5 SVG Tab滑块菜单 非常酷的Tab菜单之前我们分享过很多HTML5/CSS…

python 矩阵合并_numpy 的矩阵合并与分割

aiblog4.jpg 这次分享下numpy中矩阵的合并与分割&#xff0c;希望能帮助到大家。 在此附上视频链接 一、引入numpy第三方库 首先我们引入numpy这个第三方库,如果有同学没安装numpy可在命令行中pip install numpy进行安装(Mac用户 sudo pip3 install numpy) import numpy as np …

微型计算机技术怎么学,浅谈微型计算机技术课程的启发式教学

摘要&#xff1a;《微型计算机技术》是一门工程性很强的课程&#xff0c;内容涵盖丰富&#xff0c;软硬件结合&#xff0c;学习难度较大。本文从寻求问题出发到实际解决该问题的过程中培养学生的学习兴趣&#xff0c;从而获得学习的主动性。关键词&#xff1a;微型计算机技术 思…

rto净化效率计算公式_你了解废气处理设备RTO蓄热式热氧化炉的工作原理么?

RTO蓄热式热氧化炉的净化效果以及稳定性都是相当不错的&#xff0c;但是由于其一次性投入成本高&#xff0c;许多企业都选择了放弃。但是科盈小编想要说的是从其99&#xff05;的净化效果、换热系统、新型蜂窝技术以及日后的运行成本费用来看&#xff0c;这个费用就显得很可观了…

Selenium 4相对定位器如何改变您的测试方式?

网页可以包含许多Web元素或GUI元素&#xff0c;例如单选按钮&#xff0c;文本框&#xff0c;下拉菜单&#xff0c;输入等。Selenium自动化测试中的Web定位器用于对页面的Web元素执行不同的操作。 毫不奇怪&#xff0c;作为新的Selenium用户&#xff0c;我们要学习的第一件事是S…

电商 php 颜色数据怎么敲?_来客说电商|电商系统开发注意事项

来客B2B2C多用户电商系统打造支持自营招商入驻经营模式的电商平台&#xff08;类似京东、天猫的经营模式&#xff09;&#xff0c;创新模块化设计整合运营商&#xff0c;供货商&#xff0c;批发商&#xff0c;入驻商&#xff0c;分销商&#xff0c;门店于一体&#xff0c;各个模…

计算机网络名词解释-csma cda,计算机专业对口升学模拟题1资料.doc

精品文档精品文档PAGE精品文档第一部分计算机组装与维护一、单项选择题(每小题1分&#xff0c;共10分)1&#xff0e;下列关于微型放松计算机特点的描述中&#xff0c;错误的是()、体积小、重量轻、功耗低B、结构简单灵活、系统设计方便&#xff0c;适应性强C、可靠性高、但对使…

朗读评价语言集锦_英语老师批改作业时的精彩评语集锦,超实用!

01你的作业评语&#xff0c;学生看得懂吗&#xff1f;评语是写给学生看的&#xff0c;所以一方面评语要使用学生能看得懂的英语来写&#xff0c;所使用的词汇和语法不能过高或过低于学生的现有水平&#xff0c;要切合学生的实际情况&#xff0c;符合学生的个性心理发展需要&…