Hibernate,懒加载还是非懒加载?

5
我有一个实体A,它与实体B存在多对多关系。
因此,表格布局如下:A、AB(映射表)、B。
要获取实体A的对象,我调用A.getById(),它使用Spring和Hibernate执行getHibernateTemplate().get(A.class, id)。
问题在于,有时候后续代码只需要A,有时候后续代码将继续访问相关的B,因此我们想在某些情况下使用延迟加载,在其他一些情况下使用急切加载。但问题是,所有数据库访问都通过同一个ADao.java提供,所以只有一个方法getById()。
我应该创建两个版本的getById()方法吗?
但是,对于更复杂的情况,如果A也通过多对多与C相连,则可能存在惰性加载-C 和 急切加载-C 的变体,因此所需的getById()变体会快速呈指数增长。
你对这个选择有什么看法?
谢谢。
2个回答

3
好的,您描述了问题的正确性。这只是在简单性(只有一个方法)和性能(两种方法,每种方法都返回所需的内容)之间进行权衡。如果使用单个方法并延迟加载B可以正确响应时间,则不要更改任何内容。如果响应时间太长,并且您已经测量了急切加载会使其正确,则引入新方法。
保持简单,并仅在需要时进行优化。惰性加载关联非常快,因为它只对外键进行查询,数据库中应该对其进行索引。
另外,请注意,加载两个toMany关联通常很少见:在页面上显示类别的所有产品很常见,但显示类别的所有产品的所有购买情况则不常见。

3

如果想了解一般性问题,请查看Hibernate 3.6文档中关于提取策略的部分。默认的提取策略在映射注释或hbm.xml文件中定义。有三种方法可以动态地从默认的延迟加载策略切换到立即加载策略。前两种方法需要为延迟加载和立即加载用例分别实现DAO方法:

  1. 在Hibernate Criteria查询中使用Criteria.setFetchMode()
  2. 在HQL查询中使用FETCH关键字
  3. 自Hibernate 3.5以来(现在不太确定,可能是3.6),有第三种选项,即使用提取配置文件动态地从延迟加载切换到立即加载。

提取配置文件在会话范围内启用/禁用。因此,只要在当前会话中设置所需的提取配置文件,您就可以将同一DAO方法用于延迟加载和立即加载用例。

在这里需要注意的重要事情是,您只能从注释或hbm.xml文件中定义的惰性加载策略切换到急切加载策略,而不能反过来。这个限制与用于切换提取策略的方法无关。

FetchProfile 很不错。有没有更新的等效物? - Tadhg

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