一尘不染

休眠性能最佳实践?

hibernate

我正在使用Hibernate 3编写Web应用程序。

所以,过了一会儿,我注意到有些东西很慢。因此,我测试了Hibernate
Profiler,发现Hibernate将无理地进行许多数据库调用以简化操作。原因当然是我加载了一个对象(该对象有几个“父母”),而这些“父母”还有其他“父母”。因此,即使我只需要基本对象,从根本上来说,hibernate都会加载它们。好的,所以我研究了延迟加载。这使我进入了Lazyloading-
exception,因为我有一个MVC webapp。

所以,现在我对我的最佳处理方法有些困惑。基本上,我所需要做的只是更新对象上的单个字段。我已经有了对象键。

我应该:1.深入研究延迟加载。然后重写我的应用程序以进行开放会话视图?2.挖掘延迟加载。然后改写我的Dao的更具体。例如编写DAO方法,该方法将仅返回实例化的对象,而每个用例都需要什么?可能有很多额外的方法…
3.从头开始hibernate并自己做吗?4. Cant现在真的在考虑其他解决方案。有什么建议么?

最佳做法是什么?


阅读 172

收藏
2020-06-20

共1个答案

一尘不染

  • 除非确实需要,否则不要使用联接。他们将不允许您既不使用延迟加载,也不使用2级缓存进行关联
  • 对大型集合使用lazy =“ extra”,它不会检索所有元素,直到您询问为止,例如,也可以使用size()方法,而无需从数据库中获取元素
  • 如果可能,请使用load()方法,因为它直到需要时才发出选择查询。例如,如果您有一本书和一本作者,并且想要将它们关联在一起,则不会发出任何选择,只能发出单个插入内容:
Book b = (Book) session.load(Book.class, bookId);
Author a = (Author) session.load(Author.class, authorId);
b.setAuthor(a);
session.save(b);
  • 使用命名查询(在hbm文件或@NamedQuery中),以便在每次查询期间都不会解析它们。除非需要,否则不要使用Criteria API(在这种情况下,无法使用PreparedStatement缓存)

  • 在您的Web应用程序中使用OSIV,因为它仅在/需要时才加载数据

  • 对只读选项使用只读模式:session.setReadOnly(object, true)。这将使Hibernate不在持久化上下文中保留所选实体的原始快照,以进行进一步的脏检查。
  • 用户2级缓存和查询缓存,用于只读和只读数据。
  • 使用FlushMode.COMMIT代替AUTO,这样Hibernate不会在更新之前发出select,但是要做好准备,以免导致写入过时的数据(尽管乐观锁定可以帮助您)。
  • 看一下批量获取(批量大小),以便一次选择多个实体/集合,而不是针对每个实体/集合发出单独的查询。
  • 进行“从实体中选择新的Entity(id,someField)”之类的查询,以便仅检索必填字段。看一下结果转换器。
  • 必要时使用批处理操作(如删除)
  • 如果使用本机查询,请明确指定哪些缓存区域应无效(默认情况下-全部)。
  • 看一下树状结构的物化路径和嵌套集。
  • 进行设置c3p0.max_statements以启用池中的PreparedStatment缓存,并启用数据库的语句缓存(如果默认情况下已关闭)。
  • 如果可能,请使用StatelessSession,它可以克服脏检查,级联,拦截器等问题。
  • 不要将分页(setMaxResults()setFirstResult())与包含对集合的联接的查询一起使用,这将导致所有记录从数据库中拉出,并且分页将在Hibernate中发生在内存中。如果要分页,理想情况下不应该使用联接。如果您无法摆脱它,请再次使用批量获取。

其实有很多技巧,但是我现在还记得不多。

2020-06-20