hibernate dao设计问题

时间:2010-08-02 07:18:48

标签: java hibernate design-patterns orm dao

我希望在我的hibernate应用程序中创建一个通用的DAO来处理CRUD。我的实体拥有大多数关联作为LAZY获取。但我发现为了让hibernate尽可能高效,我必须在我的DAO上创建多个方法。这就是我的意思:

实体A有两个关联。有时候我想在不加载关联的情况下检索这个实体,有时候我希望它完全填充,所以我在DAO上放了两个方法:

getWhatever()
getWhateverWithLoadedAssociations()

我有两个不同的查询,一个没有连接提取,另一个连接提取。结果是hibernate总是做一次选择,无论它是否为LAZY,因为我知道我想要的是什么。

这个问题是,在保存一两个SELECT时,由于方法的数量而增加了复杂性。

这是极端的吗?我应该只使用getWhatever()并让hibernate在我需要关联数据时再做一次选择,即使我可以保存而不执行SELECT吗?

我希望这不会太混乱。我试图计算由于延迟加载而导致的SELECTS数量与代码复杂性相比的成本

感谢

6 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分:2)

我认为这可能有资格成为过早优化。换句话说,除非你确定那里存在性能问题,否则不要这样做。

现在让Hibernate执行其延迟抓取,如果应用程序太慢,您可以开始只在需要的地方添加这些方法。

答案 2 :(得分:2)

  

这是极端的吗?我应该只使用getWhatever()并让hibernate在我需要关联数据时再做一次选择,即使我可以保存而不执行SELECT吗?

如果启用了延迟关联/提取,那么如果一段不需要关联的代码调用getWhatever()getWhateverWithLoadedAssociations(),会有什么区别?它应该导致相同数量的SQL查询。

如果您只有一个getWhatever()方法,请检查可能性:

  1. 一段代码不访问关联 - 没有触发加载关联的SQL查询
  2. 一段代码确实访问了关联 - 触发加载关联的SQL查询。
  3. 在任何一种情况下,只在需要时加载关联。

    延迟加载的目的是让你不必担心这种类型的事情 - 如果调用DAO方法的代码访问关联,那么它就被加载了;如果不是,它不是。

答案 3 :(得分: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

答案 4 :(得分:0)

你可以有一个共同的(在基类中)dao方法:

public void initialize(Object entity);

您致电Hibernate.initialize(entity);

的地方

答案 5 :(得分:0)

在我看来,是的,你是极端的。

除非您正在使用这些查询的thousends开发批处理过程,否则执行单个查询与hibernate在加载懒惰时执行的查询之间没有太大区别。

无论如何,如果您已经确认了对应用程序性能的担忧,那么您提出的建议并不是一种糟糕的做法。