初始化懒惰关系以及何时使用它们的5种方法

实体之间关系的延迟加载是JPA中公认的最佳实践。 它的主要目标是仅从数据库中检索请求的实体,并仅在需要时加载相关实体。 如果我们只需要请求的实体,那是一个很好的方法。 但是,如果我们还需要一些相关实体,它会增加工作量,并可能导致性能问题。

让我们看一下触发初始化的不同方法及其特定的优点和缺点。

5

1.在映射关系上调用方法

让我们从最显而易见的方法开始,不幸的是也从效率最低的方法开始。 我们在EntityManager上使用find方法,并在关系上调用一个方法。

Order order = this.em.find(Order.class, orderId);
order.getItems().size();

此代码工作得很好,易于阅读并且经常使用。 那么,这是什么问题呢?

好吧,您可能知道。 此代码执行附加查询以初始化关系。 这听起来不像是一个真正的问题,但是可以让我们计算出一个更加真实的场景中执行的查询的数量。

假设我们有一个具有5个关系的实体,需要初始化。 因此,我们将获得1 + 5 = 6个查询 。 好的,那是5个附加查询。 这似乎仍然不是一个大问题。

但是我们的应用程序将被多个用户并行使用(我希望)。 假设我们的系统必须为100个并行用户提供服务器。 然后,我们将获得100 + 5 * 100 = 600个查询

好的,很明显,这种方法提供了可行的解决方案,但不是一个好的解决方案。 或早或晚,额外执行的查询数量将使我们的应用程序变慢。 因此,我们应该尝试避免这种方法,并看看其他一些选择。

2.在JPQL中获取Join

初始化惰性关系的一个更好的选择是将JPQL查询与获取联接一起使用。

Query q = this.em.createQuery("SELECT o FROM Order o JOIN FETCH o.items i WHERE o.id = :id");
q.setParameter("id", orderId);
newOrder = (Order) q.getSingleResult();

这告诉实体管理器在同一查询中获取选定的实体和关系。 这种方法的优缺点很明显:

优点是所有内容都在一个查询中获取。 从性能的角度来看,这比第一种方法要好得多。

主要缺点是我们需要编写其他代码来执行查询。 但是,如果实体具有多个关系,并且我们需要针对不同的用例初始化不同的关系,那就更糟了。 在这种情况下,我们需要为获取联接关系的每个所需组合编写查询。 这会变得很混乱。

在JPQL语句中使用提取联接可能需要大量查询,这将使维护代码库变得困难。 因此,在开始编写大量查询之前,我们应该考虑可能需要的不同访存联接组合的数量。 如果数量很少,那么这是一种限制执行的查询数量的好方法。

3.获取条件API中的加入

好的,这种方法与以前的方法基本相同。 但是这次我们使用的是Criteria API,而不是JPQL查询。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery q = cb.createQuery(Order.class);
Root o = q.from(Order.class);
o.fetch("items", JoinType.INNER);
q.select(o);
q.where(cb.equal(o.get("id"), orderId));Order order = (Order)this.em.createQuery(q).getSingleResult();

优点和缺点与带有访存连接的JPQL查询相同。 使用一个查询从数据库中检索实体和关系,我们需要每种关系组合的特定代码。 但是,如果我们使用的是Criteria API,我们通常已经有很多用例特定的查询代码。 因此,这可能不是一个大问题。

如果我们已经在使用Criteria API来构建查询,那么这是减少执行查询数量的好方法。

4.命名实体图

命名实体图是JPA 2.1的新功能。 它可用于定义应从数据库中查询的实体图。 实体图的定义是通过注释完成的,并且与查询无关。

如果您不熟悉此功能,则可以查看我以前的一篇博客文章 ,其中对它进行了更详细的介绍。

@Entity
@NamedEntityGraph(name = "graph.Order.items", attributeNodes = @NamedAttributeNode("items"))
public class Order implements Serializable {
....

然后,EntityManager的find方法可以使用命名的实体图。

EntityGraph graph = this.em.getEntityGraph("graph.Order.items");Map hints = new HashMap();
hints.put("javax.persistence.fetchgraph", graph);Order order = this.em.find(Order.class, orderId, hints);

这基本上是我们第一种方法的改进版本。 实体管理器将通过一个查询从数据库检索定义的实体图。 唯一的缺点是,我们需要为将在一个查询中检索到的每种关系组合注释一个命名实体图。 与第二种方法一样,我们将需要更少的附加注释,但是它仍然会变得非常混乱。

因此,如果我们只需要定义有限数量的实体图并将其重用于不同的用例,则命名实体图是一个很好的解决方案。 否则,代码将变得难以维护。

5.动态实体图

动态实体图类似于命名实体图,并且在以前的一篇文章中也进行了解释。 唯一的区别是,实体图是通过Java API定义的。

EntityGraph graph = this.em.createEntityGraph(Order.class);
Subgraph itemGraph = graph.addSubgraph("items");Map hints = new HashMap();
hints.put("javax.persistence.loadgraph", graph);Order order = this.em.find(Order.class, orderId, hints);

通过API进行定义既可以是优点,也可以是缺点。 如果我们需要大量用例特定的实体图,则最好在特定的Java代码中定义实体图,并且不向该实体添加附加注释。 这样可以避免带有数十个注释的实体。 另一方面,动态实体图需要​​更多代码和其他方法才能重用。

因此,我建议使用动态实体图,如果我们需要定义用例特定的图,则将不会重复使用该图。 如果我们想重用实体图,则更容易注释命名的实体图。

结论

我们研究了5种不同的初始化惰性关系的方法。 正如我们所看到的,它们每个都有其优点和缺点。 那么从这篇文章中要记住什么呢?

  • 通过在映射关系上调用方法来初始化惰性关系会导致附加查询。 出于性能原因,应避免这种情况。
  • JPQL语句中的访存联接将查询数量减少到一个,但是我们可能需要很多不同的查询。
  • Criteria API还支持提取连接,对于每种需要初始化的关系,我们都需要特定的代码。
  • 如果我们将在代码中重用已定义的图,则命名实体图是一个很好的解决方案。
  • 如果我们需要定义特定于用例的图,则动态实体图可能是更好的解决方案。

翻译自: https://www.javacodegeeks.com/2014/12/5-ways-to-initialize-lazy-relations-and-when-to-use-them.html

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

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

相关文章

fieldset ----- 不常用的HTML标签

fieldset 元素可将表单内的相关元素分组。 <fieldset> 标签将表单内容的一部分打包&#xff0c;生成一组相关表单的字段。 当一组表单元素放到 <fieldset> 标签内时&#xff0c;浏览器会以特殊方式来显示它们&#xff0c;它们可能有特殊的边界、3D 效果&#xff…

使用入站适配器公开HTTP Restful API。 第1部分(XML)

1.简介 这篇文章的目的是使用Spring Integration HTTP入站适配器实现HTTP Restful API。 本教程分为两个部分&#xff1a; XML配置示例&#xff08;同一篇文章&#xff09;。 Java DSL示例。 这将在本教程的下一部分中进行说明&#xff0c;展示如何使用Spring Integration Ja…

使用jOOQ和JavaFX将SQL数据转换为图表

最近&#xff0c;我们已经展示了Java 8和函数式编程将如何为使用jOOQ和Java 8 lambda和Streams进行SQL数据的函数数据转换为Java开发人员带来新的视角。 今天&#xff0c;我们将这一步骤更进一步&#xff0c;将数据转换为JavaFX XYChart.Series以根据数据生成美观的条形图。 设…

node.js学习笔记(1)

一&#xff0e; 安装以及环境配置 安装路径 http://nodejs.cn/download/ 多种环境选择 环境变量的配置 Step1 先检查环境变量中的系统变量里面的path,查看是否加入了node.js 例如我的node.js安装路径是C:\Program Files\nodejs 那么&#xff0c;这个path里面就应该加…

主要版本发布后Java开发人员应使用的15种工具

新部署的生存工具包&#xff1a;适用于Java开发人员的工具&#xff0c;这些工具经常将代码部署到生产中&#xff01; Takipi会检测生产中的所有错误&#xff0c;并像发生错误时一样显示变量值 立即部署并获得免费的T恤 适用于新部署的终极生存套件 与在僵尸末日场景下玩弄&…

Java EE 7批处理和魔兽世界–第2部分

今天&#xff0c;我将把第二部分带到我以前关于Java EE 7批处理和《魔兽世界–第1部分》的帖子中。 在本文中&#xff0c;我们将了解如何从第1部分中获得的数据中汇总和提取指标。 概括 批处理目的是下载魔兽世界拍卖行的数据&#xff0c;处理拍卖并提取指标。 这些指标将建立…

js导航条 二级滑动 模仿块级作用域

for(var i 1;i<7;i){    //因为首级标题有6个&#xff0c;对每个首级标题添加mouseover和mouseout事件。    //这里用到块级作用域(function(k){document.getElementById("p_"k).addEventListener(mouseover,function(event){document.getElementById(p_…

struts+swfupload实现批量图片上传(上):swfupload

custom_settings : {progressTarget : "fsUploadProgress",cancelButtonId : "btnCancel",uploadButtonId : "btnUpload",myFileListTarget : "idFileList" },custom_settings调用方法 this.customSettings.cancelButtonId 缩略图js …

40行中的持久性KeyValue Server和一个可悲的事实

再次出现。. 回顾 Peters关于Unsafe用法的书面概述 &#xff0c;我将简要介绍一下Java中的低级技术如何通过启用更高级别的抽象或允许Java性能级别来节省开发工作可能很多人都不知道。 我的主要观点是表明&#xff0c;将对象转换为字节&#xff0c;反之亦然是一个重要的基础&a…

TreeMap源码分析——深入分析(基于JDK1.6)

TreeMap有Values、EntrySet、KeySet、PrivateEntryIterator、EntryIterator、ValueIterator、KeyIterator、DescendingKeyIterator、NavigableSubMap、AscendingSubMap、DescendingSubMap、SubMap、Entry共十三个内部类。Entry是在TreeMap中用于表示树的节点的内部类&#xff0…

Python2.6 Cx_Oracle Linux下编译安装

分类&#xff1a; python Oracle 2012-06-07 00:04 239人阅读 评论(0) 收藏 举报(一) Python 2.6 安装 1.下载Python2.6.X 版本的源码包&#xff0c;这里采用平台编译安装。 Python-2.6.4.tar.bz2 2.解压缩 ,使用J参数解压bigz2类型的压缩文件 tar -jxvf Python-2.6.4.tar.bz2…

Apache TomEE(和Tomcat)的自签名证书

可能在大多数Java EE项目中&#xff0c;您将拥有具有SSL支持&#xff08; https &#xff09;的部分或整个系统&#xff0c;因此浏览器和服务器可以通过安全连接进行通信。 这意味着在处理数据之前&#xff0c;已发送的数据已加密&#xff0c;传输并最终解密。 问题在于&…

WEB效能测试和负载测试部分截图

效能测试&#xff1a; 负载测试&#xff1a; 转载于:https://www.cnblogs.com/DOOM-scse/archive/2013/01/07/2849110.html

Java8 Lambdas:解释性能缺陷的排序

与Peter Lawrey合作撰写 。 几天前&#xff0c;我对使用新的Java8声明式的排序性能提出了严重的问题。 在这里查看博客文章。 在那篇文章中&#xff0c;我仅指出了问题所在&#xff0c;但在这篇文章中&#xff0c;我将更深入地了解和解释问题的原因。 这将通过使用声明式样式重…

Asp.net MVC3.0 基于不同的角色显示不同的菜单

前面提到过用Asp.net MVC3.0正在做一个问答系统性质的论坛。前期把菜单全部显示以方便测试模块功能。现在正在完善&#xff0c;加上角色模块&#xff0c;然后不同的角色登陆系统会看到不同的菜单栏&#xff0c;还有就是游客&#xff08;未登录用户&#xff09;看到的菜单栏。网…

LoadRunner如何监控Linux下的系统资源

前一段时间在研究LoadRunner过程中&#xff0c;在进行压力场景测试中通过LoadRunner来实时监控windows的系统资源&#xff0c;在前几节中我已经总结了相关过程&#xff0c;近段时间发现群里有朋友问如何监控Linux下的系统资源&#xff0c;所以我也就此问题搭建了一些的Linux环境…

页面跳转多种方法(加传参)

onclick"javascript:location.href/HelpCenter/HelpCenter/" <a href"/HelpCenter/HelpCenter">帮助中心</a>点击页面返回上一页&#xff1a; onclick"javascript:window.history.go(-1); *********************************************…

JCG学院开设了Java设计模式课程!

自从我们推出JCG学院以来&#xff0c;已经有一段时间了。JCG学院是一个基于付费内容的高级订阅网站&#xff0c;提供有关最新技术的课程&#xff0c;涵盖从RedSQL数据库&#xff08;如Redis和CouchDB&#xff09;到使用Android进行移动开发的最新知识。 当然&#xff0c;与Jav…

用友异常清理工具

此类工具网上很多&#xff0c;但&#xff0c;网上的病毒千千万万&#xff0c;还是自己开发使用较为放心。而且具体执行了什么也一清二楚&#xff0c;可以放心。 此工具适用大部份版本&#xff0c;从U821至U871&#xff0c;包括U6系列。 转载于:https://www.cnblogs.com/wuxi15/…

JVM因“ OutOfMemory”错误而关闭-我该怎么办?

看起来似乎很神奇&#xff0c;但是在有关JVM设置的搜索请求结果中经常显示这种“从深度”的呼喊。 您可能会遇到“我记得该选项&#xff0c;但如何启用它”的问题&#xff0c;而有时&#xff08;主要是半年一次&#xff09;管理服务器或调整虚拟设备&#xff0c;而又除主要任务…