多语言展示
当前在线:1637今日阅读:82今日分享:48

Hibernate会对性能产生什么影响?

Hibernate会对性能产生什么影响?
工具/原料
1

hibernate

2

IntelliJ IDEA

方法/步骤
1

默认情况下,Hibernate实体会被急切地检索;也就是说,当您从数据库检索对象时,也同时检索任何依赖对象。对于售票处,检索Person对象也将检索其相关的票务对象和事件对象。

2

这可能是一个相当昂贵、耗时的操作。对于一个真正的票务系统,它可能包含数千个事件,每个事件都可能有数万张票,检索所有这些对象没有多大意义。

3

值得庆幸的是,Hibernate允许您延迟加载对象;也就是说,查询将在需要时发生。

4

下图显示了如何对Ticket对象执行此操作。如果将票证和事件设置为延迟加载,那么在检索Person对象时,只有在尝试访问票证集引用或事件引用时,才会从数据库加载它们的票证和事件。

5

要使对象延迟加载,需要向Hibernate映射中的相关属性添加lazy='proxy'属性。

6

为了证明这一点,无论何时访问person的Ticket对象,如果仍然打开show_sql属性,就会看到Hibernate记录查询。

7

然而,有可能做得更好来证明这一点。通过记录创建事件对象的时间,您可以确定它们是在正确的时间创建的。下图显示了可以对Event类进行的一些临时更改。

8

如果您不熟悉AtomicInteger类,简单地说,它是一个整数的持有者,可以通过线程安全的方式访问这个整数进行读写。

9

通过添加静态计数器,可以在适当的时候全局引用并检查它。值得强调的是,这不是一个好的设计,也不是特别安全的代码,但是在这里,它可以很好地证明这一点。

10

只需要在无参数构造函数中增加计数器;因为这是Hibernate在构造事件时使用的惟一构造函数。

11

下图显示了如何确定事件是延迟加载的。

12

可以看看延迟加载的日志:

13

关于这个测试,你应该注意几点。首先,调用Hibernate之前将constructedInstances 变量重置为零,即使在类初始化时将其设置为零。这是因为Hibernate会在测试开始时重新创建这些对象,以确保映射是正确的。

14

如果system . out.println被删除,并且检索到的Person对象从未被引用,编译器可能会完全删除检索,因为Person对象永远不会被使用。

15

检索Person对象之后,计数器应该仍然为零,即使Hibernate已经从数据库中收集了Person,而且似乎可以访问票据集。

16

一旦获取了票据并引用了它们的事件对象,就会创建事件。这可以通过事件构造函数增加计数器来验证。

17

您应该能够看到用测试打印的行与Hibernate日志记录交织在一起,以便从数据库中提取事件细节。如果从Tickets.hbm.xml映射中删除lazy属性,测试将会失败,正如您所期望的那样。

推荐信息