JPA 2.1实体图–第1部分:命名实体图

延迟加载通常是JPA 2.0的问题。 如果要使用FetchType.LAZY(默认)或FetchType.EAGER来加载关系,则必须在实体上进行定义,并且始终使用此模式。 仅当我们要始终加载关系时才使用FetchType.EAGER。 FetchType.LAZY几乎在所有情况下都用于获得性能良好且可伸缩的应用程序。

但这并非没有缺点。 如果必须使用关系的元素,则需要确保在从数据库加载实体的事务中初始化该关系。 这可以通过使用特定的查询来完成,该查询从数据库中读取实体和所需的关系。 但这将导致用例特定的查询。 另一个选择是在您的业务代码中访问该关系,这将导致对每个关系的附加查询。 两种方法都不完美。

JPA 2.1实体图是一个更好的解决方案。 实体图的定义与查询无关,并且定义了要从数据库中获取哪些属性。 实体图可以用作访存图或负载图。 如果使用提取图,则仅由实体图指定的属性将被视为FetchType.EAGER。 所有其他属性将是惰性的。 如果使用负载图,则实体图未指定的所有属性将保留其默认提取类型。

让我们看看如何定义和使用实体图。

示例实体

在此示例中,我们将使用带有项目列表的订单,每个项目都有一个产品。 所有关系都是懒惰的。

订单实体:

@Entity
@Table(name = "purchaseOrder")
@NamedEntityGraph(name = "graph.Order.items", attributeNodes = @NamedAttributeNode(value = "items", subgraph = "items"), subgraphs = @NamedSubgraph(name = "items", attributeNodes = @NamedAttributeNode("product")))
public class Order implements Serializable {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id", updatable = false, nullable = false)private Long id = null;@Version@Column(name = "version")private int version = 0;@Columnprivate String orderNumber;@OneToMany(mappedBy = "order", fetch = FetchType.LAZY)private Set<OrderItem> items = new HashSet<OrderItem>();...

OrderItem实体:

@Entity
public class OrderItem implements Serializable
{@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id", updatable = false, nullable = false)private Long id = null;@Version@Column(name = "version")private int version = 0;@Columnprivate int quantity;@ManyToOneprivate Order order;@ManyToOne(fetch = FetchType.LAZY)private Product product;

产品实体:

@Entity
public class Product implements Serializable
{@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id", updatable = false, nullable = false)private Long id = null;@Version@Column(name = "version")private int version = 0;@Columnprivate String name;

命名实体图

命名实体图的定义是通过实体上的@NamedEntityGraph批注完成的。 它定义了唯一的名称和已加载的属性列表( attributeNodes )。

以下示例显示了实体图“ graph.Order.items”的定义,该图将加载OrderOrderItem列表。

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

现在我们已经定义了实体图,我们可以在查询中使用它。 因此,我们需要创建一个具有查询提示的Map,并将其设置为find或query方法调用上的附加参数。

以下代码段显示了如何在find语句中使用命名实体图作为获取图。

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

命名子图

我们使用实体图来定义Order实体的提取操作。 如果我们想对OrderItem实体执行相同的操作,则可以使用实体子图执行此操作。 命名子图的定义类似于命名实体图的定义,并且可以引用为attributeNode。

以下代码段显示了用于加载每个OrderItemProduct的子图的定义。 定义的实体图将获取包含所有OrderItem及其产品Order

@Entity
@Table(name = "purchase_order")
@NamedEntityGraph(name = "graph.Order.items", attributeNodes = @NamedAttributeNode(value = "items", subgraph = "items"), subgraphs = @NamedSubgraph(name = "items", attributeNodes = @NamedAttributeNode("product")))
public class Order implements Serializable {

里面发生什么事了?

好的,从发展的角度来看,实体图很棒。 它们易于使用,我们不需要编写其他代码来避免延迟加载问题。 但是里面发生了什么? 有多少查询发送到数据库? 让我们看看休眠调试日志。

2014-03-22 21:56:08,285 DEBUG [org.hibernate.loader.plan.build.spi.LoadPlanTreePrinter] (pool-2-thread-1) LoadPlan(entity=blog.thoughts.on.java.jpa21.entity.graph.model.Order) - Returns - EntityReturnImpl(entity=blog.thoughts.on.java.jpa21.entity.graph.model.Order, querySpaceUid=<gen:0>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order) - CollectionAttributeFetchImpl(collection=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items, querySpaceUid=<gen:1>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items) - (collection element) CollectionFetchableElementEntityGraph(entity=blog.thoughts.on.java.jpa21.entity.graph.model.OrderItem, querySpaceUid=<gen:2>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items.<elements>) - EntityAttributeFetchImpl(entity=blog.thoughts.on.java.jpa21.entity.graph.model.Product, querySpaceUid=<gen:3>, path=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items.<elements>.product) - QuerySpaces - EntityQuerySpaceImpl(uid=<gen:0>, entity=blog.thoughts.on.java.jpa21.entity.graph.model.Order) - SQL table alias mapping - order0_ - alias suffix - 0_ - suffixed key columns - {id1_2_0_} - JOIN (JoinDefinedByMetadata(items)) : <gen:0> -> <gen:1> - CollectionQuerySpaceImpl(uid=<gen:1>, collection=blog.thoughts.on.java.jpa21.entity.graph.model.Order.items) - SQL table alias mapping - items1_ - alias suffix - 1_ - suffixed key columns - {order_id4_2_1_} - entity-element alias suffix - 2_ - 2_entity-element suffixed key columns - id1_0_2_ - JOIN (JoinDefinedByMetadata(elements)) : <gen:1> -> <gen:2> - EntityQuerySpaceImpl(uid=<gen:2>, entity=blog.thoughts.on.java.jpa21.entity.graph.model.OrderItem) - SQL table alias mapping - items1_ - alias suffix - 2_ - suffixed key columns - {id1_0_2_} - JOIN (JoinDefinedByMetadata(product)) : <gen:2> -> <gen:3> - EntityQuerySpaceImpl(uid=<gen:3>, entity=blog.thoughts.on.java.jpa21.entity.graph.model.Product) - SQL table alias mapping - product2_ - alias suffix - 3_ - suffixed key columns - {id1_1_3_} 2014-03-22 21:56:08,285 DEBUG [org.hibernate.loader.entity.plan.EntityLoader] (pool-2-thread-1) Static select for entity blog.thoughts.on.java.jpa21.entity.graph.model.Order [NONE:-1]: select order0_.id as id1_2_0_, order0_.orderNumber as orderNum2_2_0_, order0_.version as version3_2_0_, items1_.order_id as order_id4_2_1_, items1_.id as id1_0_1_, items1_.id as id1_0_2_, items1_.order_id as order_id4_0_2_, items1_.product_id as product_5_0_2_, items1_.quantity as quantity2_0_2_, items1_.version as version3_0_2_, product2_.id as id1_1_3_, product2_.name as name2_1_3_, product2_.version as version3_1_3_ from purchase_order order0_ left outer join OrderItem items1_ on order0_.id=items1_.order_id left outer join Product product2_ on items1_.product_id=product2_.id where order0_.id=?

日志显示仅创建了一个查询。 Hibernate使用实体图来创建具有所有3个实体( OrderOrderItemProduct )的加载计划,并通过一个查询加载它们。

结论

我们定义了一个实体图,该图告诉实体管理器从数据库中获取3个相关实体的图( OrderOrderItemProduct )。 实体图的定义和用法与查询无关,并且仅产生一条select语句。 因此,解决了JPA 2.0方法的主要缺点(在开头提到)。

从我的角度来看,新的实体图功能确实很棒,并且可以解决延迟加载问题。 你怎么看待这件事?

翻译自: https://www.javacodegeeks.com/2014/05/jpa-2-1-entity-graph-part-1-named-entity-graphs.html

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

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

相关文章

课时85.层叠性(掌握)

1.什么是层叠性&#xff1f; 层叠性就是CSS处理冲突的一种能力。 这个字体最终会变为红色 注意点&#xff1a; 层叠性只有在多个选择器选中“同一个标签”,然后又设置了“相同的属性”&#xff0c;才会发生层叠性。 CSS全称&#xff1a;Cascading StyleSheet 层叠样式表&am…

ABZ职业规划

关于职业规划&#xff0c;LinkedIn&#xff08;领英&#xff09;创始人里德霍夫曼&#xff08;Reid Hoffman&#xff09;提出著名的“ABZ理论”&#xff0c;教我们应对变化莫测的职场人生。 德霍父曼建议每个职场人应有A计划&#xff0c;B计划&#xff0c;C计划。 A计划&#x…

SetProcessWorkingSetSize减少内存占用

系统启动起来以后&#xff0c;内存占用越来越大&#xff0c;使用析构函数、GC.Collect什么的也不见效果&#xff0c;后来查了好久&#xff0c;找到了个办法&#xff0c;就是使用 SetProcessWorkingSetSize函数。这个函数是Windows API 函数。下面是使用的方法&#xff1a;[Syst…

Spring Boot 与消息 (JMS、AMQP、RabbitMQ)

RabbitMQ教程 - 鸟哥的专栏 - CSDN博客 一、概述 大多应用中&#xff0c;可通过消息服务中间件来提升系统异步通信、扩展解耦能力消息服务中两个重要概念&#xff1a;消息代理&#xff08;message broker)和目的地&#xff08;destination) 当消息发送者发送消息以后&#xff0…

使用Apache Camel通过soap添加WS-Security

WS-Security&#xff08;Web服务安全性&#xff09;是一种协议&#xff0c;可让您保护自己的soap Web服务。 发出Soap请求的客户端必须在Soap标头中提供登录名和密码。 服务器接收到肥皂请求&#xff0c;检查凭据并验证请求是否正确。 使用Apache Camel&#xff0c;可以很容易…

课时3.浏览器访问网页原理(理解)

浏览器访问网页原理&#xff08;理解&#xff09; 第一次打开IE6&#xff0c;发现系统自动生成了一个文件夹&#xff0c;所以我们可以得出这个文件夹必然和IE6有一定的关系先删除Internet Cache下的所有文件夹&#xff0c;然后通过IE6打开百度的首页&#xff0c;打开百度首页以…

matlab 图像平移操作

目标&#xff1a;对原图I进行[80,50]的偏移操作得到图B。 首先读入图像&#xff0c;以matlab自带的pout.tif为例. strel是创建形态学结构元素的. translate函数在原结构上进行[80,50]的偏移. I imread(cameraman.tif); se translate(strel(1),[80,50]); B imdilate(I,se);转…

爬虫之基于线程池异步抓取

from multiprocessing.dummy import Pool #线程池模块#必须只可以有一个参数 def my_requests(url):return requests.get(urlurl,headersheaders).textstart time.time() urls [http://127.0.0.1:5000/bobo,http://127.0.0.1:5000/jay,http://127.0.0.1:5000/tom, ]pool Poo…

使用xjc一秒钟生成您的JAXB类

由于JAXB是JDK的一部分&#xff0c;因此它是处理XML文档最常用的框架之一。 它提供了一种从XML文档检索数据并将其存储到Java类的简便方法。 因为几乎每个Java开发人员都已经使用过JAXB&#xff0c;所以我不会解释不同的JAXB批注。 相反&#xff0c;我将专注于一个名为xjc的命令…

课时27.base(掌握)

base标签就是专门用来统一的指定当前网页中所有的超链接&#xff08;a标签&#xff09;需要如何打开格式 <base target"_blank"> <a href"https://www.baidu.com">百度</a> 注意点&#xff1a; base标签必须写在head标签的开始标签和…

async await详解

async await本身就是promise generator的语法糖。 本文主要讲述以下内容 async awiat 实质async await 主要特性async await 实质 下面使用 promise generate 实现 async await // 转换目标 async1// async function async1() {// console.log(async1 start);// await …

JavaOne 2014 –有关提交的一些初步分析

这些天时间不多了。 并行发生的事情如此之多&#xff0c;当然&#xff0c;最重要的Java会议就是一切。 JavaOne 2014已经关闭了CfP门&#xff0c;投票正在进行中。 程序委员会几乎没有什么可以谈论的&#xff0c;但是去年跳过了这种分析之后&#xff0c;现在是我该寻求许可的时…

【搜索】$P1092$虫食算

【搜索】\(P1092\)虫食算 题目链接 首先&#xff0c;我们只考虑加法的虫食算。这里的加法是N进制加法&#xff0c;算式中三个数都有N位&#xff0c;允许有前导的0。 其次&#xff0c;虫子把所有的数都啃光了&#xff0c;我们只知道哪些数字是相同的&#xff0c;我们将相同的数字…

【译】XNA Shader 程序设计(二)

XNA Shader 程序设计 教程2 - 漫反射 大家好&#xff0c;今天我们将在教程一的基础上继续学习&#xff0c;在光照算式中加上漫反射光。 漫反射光 环境光计算等式为&#xff1a; I Aintensity * Acolor 漫反射基于这个等式&#xff0c;添加了一道有方向的光线&#xff1a; I A…

Jquery基础之DOM操作

Dom是Document Object Model的缩写&#xff0c;意思是文档对象模型。DOM是一种与浏览器、平台、语言无关的接口&#xff0c;使用该接口可以轻松访问页面中所有的标准组件。DOM操作可以分为三个方面即DOM Core(核心)、HTM-DOM和CSS-DOM。 JQuery中的DOM操作主要对包括&#xff…

linux 下 `dirname $0` shell 获取当前正在执行脚本的绝对路径

【】&#xff0c;学名叫“倒引号”&#xff0c; 如果被“倒引号”括起来&#xff0c; 表示里面需要执行的是命令。比如 dirname $0&#xff0c; 就表示需要执行 dirname $0 这个命令【“”】 &#xff0c; 被双引号括起来的内容&#xff0c; 里面 出现 $ (美元号&#xf…

具有angularjs资源的Spring Rest Controller

Angularjs ngResource是用于与基于REST的服务进行交互的angularjs模块。 我最近在Spring MVC的一个小型项目中使用了它&#xff0c;并希望记录一个对我来说很好的配置。 该控制器在工厂中运行&#xff0c;它支持在酒店实体上进行CRUD操作&#xff0c;并支持以下方法&#xff1…

PAT乙级1023

题目链接 https://pintia.cn/problem-sets/994805260223102976/problems/994805298269634560 题解 主要就是控制首位不能为0&#xff0c;其他的都很简单&#xff0c;就遍历然后往尾部加数字就好了。 // PAT BasicLevel 1023 // https://pintia.cn/problem-sets/994805260223102…

js中var、let、const区别

//1.var定义的变量可以修改&#xff0c;如果不初始化会输出undefined&#xff0c;不会报错。 var a; console.log(a); //undefined//2.let是块级作用域&#xff0c;函数内部使用let定义后&#xff0c;对函数外部无影响。 let c 3; console.log(c)function change(){ let c 6;…

2000错误信息:MMC创建无法管理单元。

系统Vista&#xff0c;安装了SQL Server 2000 SP4&#xff0c;然后安装了Microsoft SQL Server 2005。后因系统太慢&#xff0c;卸载SQL SERVER2005,结果在打开 SQLServer2000的 企业管理器&#xff0c;收到以下错误信息&#xff1a;MMC创建无法管理单元。到网上寻找了以后&…