java - 对象关系映射和性能

标签 java performance hibernate

我目前正在开发一款与 Hibernate (HQL) 配合使用的产品,以及另一款与 JPQL 配合使用的产品。尽管我很喜欢从关系结构(数据库)到对象(Java 类)映射的概念,但我对其性能并不确信。

示例:

Java:

public class Person{
     private String name;
     private int age;
     private char sex;
     private List<Person> children;

     //...
}

我想获取某个Person的属性age。一个人有10个 child (他一直很忙)。使用 Hibernate 或 JPQL,您可以将人员作为对象进行检索。

HQL:

SELECT p
FROM my.package.Person as p
WHERE p.name = 'Hazaart'

我不仅会检索我不需要的人的其他属性,还会检索该人的所有子项及其属性。他们也可能有 child 等等...这意味着将在数据库级别访问比需要的更多的表。

结论:

我了解对象关系映射的优点。然而,在很多情况下,您似乎不需要某个对象的每个属性。尤其是在复杂的系统中。看起来这些优势并不能证明性能损失是合理的。我一直认为性能应该是主要关注点。

有人可以分享一下他们的意见吗?也许我以错误的方式看待它,也许我以错误的方式使用它......

最佳答案

我不熟悉 JPQL,但如果你正确设置 Hiernate,它不会自动获取子项。相反,它会返回一个代理列表,如果被访问,它将透明地获取丢失的数据。

这也适用于对其他持久对象的简单引用。 Hibernate 将创建一个仅包含 ID 的代理对象,并且仅在访问时才加载实际数据。 (“延迟加载”)

这当然有一些限制(例如持久类层次结构),但总体效果很好。

顺便说一句,你应该使用List<Person>给 children 引用。如果您指定特定的实现,我不确定 Hibernate 是否可以使用代理列表。

更新:

在上面的示例中,Hibernate 将加载属性名称、年龄和性别,并创建一个 List<Person>最初不包含数据的代理对象。

一旦应用程序访问调用列表中需要了解数据的任何方法,例如 childen.size()或者迭代列表,代理将调用 Hibernate 来读取子对象并填充列表。 children 反对,因为是 Person 的实例,还将包含代理 List<Person> 他们的 child 。

Hibernate 可能会在后台执行一些优化,例如同时加载此 session 中可能存在的其他 Person 对象的子对象,因为它无论如何都会查询数据库。但是否这样做以及达到什么程度,是可以根据属性进行配置的。

如果您确定稍后需要它们,或者 session 关闭后继续使用持久对象,您还可以告诉 hibernate 不要对某些引用或类使用延迟加载。

请注意,如果 session 不再处于 Activity 状态,延迟加载当然会失败。例如,如果您加载一个 Person 对象,不访问子列表,并关闭 session ,则调用 children.size()例如会失败。

IIRC hibernate session 类有方法在需要时填充持久对象中所有尚未加载的引用。

最好阅读 hibernate 文档来了解如何配置这一切。

关于java - 对象关系映射和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28083687/

相关文章:

c# - 在 C# 中 frac 函数的最快实现

javascript - Jquery - IE 滚动中的断断续续的动画

java - JPA注释复合主键也是一对多外键

java - 有没有办法断言枚举自上次修订以来没有改变?

java - SecondaryLoop 而不是 SwingWorker?

java - 如何让我的寻路算法不走反方向?

java - oracle海量数据复杂报表

java - 正确编写具有用于 View 绑定(bind)的属性的模型

mysql - 对大型 MySQL 表的简单查询一开始需要很长时间,之后会快得多

Spring data jpa Query动态传递where子句