我有一个日常批处理过程,其中涉及选择大量记录并格式化文件以发送到外部系统。我还需要将这些记录标记为已发送,以便明天不会再次发送它们。
在我幼稚的 JDBC 方式中,我会准备并执行一个语句,然后开始循环遍历记录集。由于我只通过记录集前进,因此我的应用程序服务器无需一次将整个结果集保存在内存中。可以从数据库服务器馈送记录组。
现在,假设我正在使用休眠。我不会一次得到一堆代表内存中整个结果集的对象吗?
我有一个日常批处理过程,其中涉及选择大量记录并格式化文件以发送到外部系统。我还需要将这些记录标记为已发送,以便明天不会再次发送它们。
在我幼稚的 JDBC 方式中,我会准备并执行一个语句,然后开始循环遍历记录集。由于我只通过记录集前进,因此我的应用程序服务器无需一次将整个结果集保存在内存中。可以从数据库服务器馈送记录组。
现在,假设我正在使用休眠。我不会一次得到一堆代表内存中整个结果集的对象吗?
Hibernate 也会遍历结果集,因此内存中只保留一行。这是默认设置。如果它贪婪地加载,你必须告诉它。
使用休眠的原因:
不使用 Hibernate 的原因:
Hibernate 提供了一些保持会话小的可能性。
您可以使用 Query.scroll()、Criteria.scroll() 进行类似 JDBC 的滚动。您可以使用 Session.evict(Object entity) 从会话中删除实体。您可以使用 StatelessSession 来抑制脏检查。还有一些更多的性能优化,请参阅 Hibernate 文档。
Hibernate 作为任何 ORM 框架旨在开发和维护基于面向对象编程主体的系统。但是大多数数据库都是关系型的,而不是面向对象的,所以无论如何,ORM 总是在方便的 OOP 编程和优化/最有效的数据库访问之间进行权衡。
我不会将 ORM 用于特定的隔离任务,而是将其用作应用程序持久层的整体架构选择。
在我看来,我不会使用 Hibernate,因为它会让你的应用程序变得更大,更难维护,而且你真的没有机会快速优化生成的 sql 脚本。此外,您可以使用 JDBC-bridge 支持的所有 SQL 功能,而不仅限于休眠功能。另一件事是,每一层遗留代码也有限制。
但归根结底,这是一个哲学问题,你应该按照最适合你的思维方式去做。
如果可能存在性能问题,请坚持使用 JDBC 代码。
有许多众所周知的纯 SQL 优化在 Hibernate 中很难做到。
只选择您使用的列!(没有“选择*”的东西)。
保持 SQl 尽可能简单。例如,不要在连接中包括像货币代码这样的小型参考表。而是将货币表加载到内存中,并通过程序查找来解析货币描述。
取决于 SQL 的 DBMS 次要重新排序,其中谓词可能对性能产生重大影响。
如果您要更新/插入,则只提交每 100 到 1000 次更新。即不要提交每个工作单元,而是保留一些计数器,以便减少提交的频率。
利用数据库的聚合函数。如果您想按部门代码计算总计,请在 SQL 中使用“ SUM(amount) ... GROUP BY DEPT ”。