Object 关系映射和性能

Object Relational mapping and performance

我目前正在开发一款适用于 Hibernate (HQL) 的产品和一款适用于 JPQL 的产品。尽管我喜欢从关系结构(数据库)映射到 object(Java class)的概念,但我对性能不满意。

示例:

Java:

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

     //...
}

我想获取某个Person的属性age。一个人10children(他一直很忙)。使用 Hibernate 或 JPQL,您可以将此人检索为 object.

HQL:

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

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

结论:

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

任何人都可以分享他们的意见吗?也许我看错了,也许我用错了...

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

这也适用于对其他持久性 object 的简单引用。 Hibernate 将创建一个代理 object,仅包含 ID,并仅在访问时加载实际数据。 ("lazy loading")

这当然有一些局限性(比如持久的 class 层次结构),但总体效果很好。

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

更新:

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

一旦应用程序访问调用需要了解数据的列表的任何方法,例如 childen.size() 或遍历列表,代理将调用 Hibernate 来读取 children objects 并填充列表。孩子 object 是 Person 的实例,也将包含 他们的 children.[=16= 的代理 List<Person> ]

hibernate 可能会在后台执行一些优化,比如同时为其他人 object 加载 children,而这可能在这个 session 中,因为它无论如何都在查询数据库。但是是否这样做以及在多大程度上可以根据属性进行配置。

你也可以告诉 hibernate 不要对某些引用或 class 使用 lazy-loading,如果你确定你以后会需要它们,或者如果你继续使用持久对象一次session 已关闭。

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

IIRC hibernate session class 有方法在需要时填充持久对象中的所有 not-yet-loaded 引用。

最好阅读有关如何配置所有这些的休眠文档。