Hibernate DAO设计问题

3
我希望创建一个通用的DAO来处理我的Hibernate应用程序中的CRUD。 我的实体大多数关联都是延迟加载的。 但是,为了使Hibernate在SELECTs方面尽可能高效,我不得不在我的DAO上创建多个方法。 这就是我的意思:
实体A有两个关联。 有时我想检索此实体而不加载关联,有时我想要完全填充它,所以我会在DAO上放置两种方法:
getWhatever()
getWhateverWithLoadedAssociations()

我将有两个不同的查询,一个没有 join fetch,另一个有 join fetch。结果是,无论是否为 LAZY,Hibernate 都会始终执行单个 select,因为我知道我想要预先获取什么。

这样做的问题是,虽然可以节省一两个 SELECT,但由于方法数量增加了复杂性。

那么这样做是否过于极端?我是否只应该有 getWhatever(),并让 Hibernate 在需要关联数据时再执行另一个 select,即使我可以通过不执行那个 SELECT 来节省呢?

希望这不太令人困惑。我正在尝试弄清楚由于 lazy loading 导致的 SELECT 数量与代码复杂性之间的代价。

谢谢

6个回答

2

您的问题是可能有太多的方法?我认为是这样,因为这些方法做了不同的事情。

如果您想要减少数量,并且正在使用HQL,则可以向该方法添加一个参数,以指示是否要连接关系:

getWhatever(WhateverFetchMode f)

其中f可以是布尔值或对象,返回字符串的HQL片段,给出要获取的关系。

public List<MyObject> getList(boolean fetchProp1) {
         return em.createQuery("select r" +
                "from Object as r " +
                fetchProp1 ? "left join fetch r.prop1 " : "")
                .getResultList();
}

或者

public List<MyObject> getList(WhateverFetchMode fetchProp1) {
         return em.createQuery("select r" +
                "from Object as r " +
                fetchProp1.toHql()) // This returns the right join fetch
                .getResultList();
}

2

我认为这可能属于过早的优化。换句话说,除非你确定有性能问题,否则不要这样做。

现在只需让Hibernate进行懒加载,如果应用程序太慢,您只需在需要时添加这些方法即可。


2
如果您启用了延迟关联/获取,那么如果不需要关联就调用 "getWhatever()" 或者调用 "getWhateverWithLoadedAssociations()" 有什么区别呢?它应该产生相同数量的SQL查询。
考虑一下如果你只有一个 "getWhatever()" 方法可能会发生的情况:
1. 如果一个代码块没有访问到关联 - 就不会触发加载关联的SQL查询。 2. 如果一个代码块访问了关联 - 就会触发加载关联的SQL查询。
在任何一种情况下,只有在需要时才会加载关联。
延迟加载的目的在于让您不必担心这种情况-如果调用DAO方法的代码访问关联,则它将被加载;如果没有,它将不会。

1
我猜这个问题与使用一个单一的查询和获取主对象及其关联的连接时的性能差异有关。这比使用多个查询更好,这也是Hibernate所做的。 - Pau

1

在我看来,我会将以下方法添加到通用DAO中:

findById(Id id);//lazy load
loadTree(Id id);//load full graph of the entity
load(Id id, String... includePaths);// just load some associations of the entity

0

你可以在一个基类中定义一个通用的dao方法:

public void initialize(Object entity);

当你调用 Hibernate.initialize(entity);


0
在我看来,是的,你有点过于极端了。
除非你正在开发一个包含成千上万个这些查询的批处理程序,否则执行单个查询和Hibernate在惰性加载时执行的查询之间没有太大区别。
无论如何,如果你对应用程序的性能有担忧,你刚刚提出的做法并不是一种坏习惯。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接