冬眠,懒惰还是不懒惰?

时间:2011-12-13 17:00:10

标签: hibernate design-patterns lazy-evaluation

我有entity A,与entity B有多对多的关系。

因此表格布局为:A, AB(mapping table), B

获取实体A的对象: 我使用spring和hibernate调用A.getById() getHibernateTemplate().get(A.class, id)

问题是,有时随后的代码只需要A,有时随后的代码将继续访问相关的B,所以我们想在某些情况下使用延迟加载并且渴望在其他一些情况下。但问题是所有数据库访问都是通过同一个ADao.java提供的,因此只有一种方法getById()

我应该创建两个版本的方法getById()吗?

但是对于更复杂的情况,如果A也通过多对多连接到C,则可能存在lazy-loading-C和eager-loading-C的变体,因此需要getById()变体迅速成倍增长。

您对此选择有何看法?

由于

2 个答案:

答案 0 :(得分:3)

嗯,你正确地描述了这个问题。这只是简单性(只有一种方法)和性能(两种方法,每种方法都能准确返回所需内容)之间的权衡。如果只使用单一方法并延迟加载Bs,响应时间是正确的,那么不要触摸任何东西。如果响应时间太长,并且您已经测量了这种急切加载它将使其正确,那么引入一种新方法。

保持简单,只在需要时进行优化。延迟加载关联很快,因为它只是对外键进行查询,应该在数据库中建立索引。

同样不是加载两个toMany协会是非常罕见的:在页面上显示一个类别的所有产品是很常见的,但是显示一个类别的所有产品的所有购买情况并不常见。

答案 1 :(得分:3)

有关一般注意事项,请查看有关fetching strategies的Hibernate 3.6文档。默认提取策略在映射注释或hbm.xml文件中定义。有三种方法可以从默认的延迟加载策略动态切换到急切加载策略。前两个需要单独实现DAO方法以实现延迟加载和急切加载用例:

    Hibernate Criteria查询中的
  1. Criteria.setFetchMode()
  2. HQL查询中的
  3. FETCH关键字
  4. 自从Hibernate 3.5(现在不太确定,可能是3.6)以来,第三种方法是使用fetch profiles来动态地从延迟加载切换到急切加载。
  5. 在会话范围上启用/禁用提取配置文件。因此,如果在当前会话中设置了所需的提取配置文件,则可以使用相同的DAO方法进行延迟加载以及急切加载用例。

    要注意的重要一点是,只能从注释或hbm.xml文件中定义的延迟加载策略切换到急切加载策略< / strong>而不是相反。此限制与用于切换提取策略的方法无关。