我正在从休眠转换回纯 JDBC,以克服使用休眠产生的开销。我想知道如何处理与休眠相关的会话。我应该如何转换回纯 JDBC,以便我的所有会话都替换为JDBC 连接。如果我认为用连接替换会话会转换回普通 JDBC 的想法有误,请告诉我,因为我不精通这些概念,也不知道我是否走对了路。
3 回答
我在高性能任务中广泛使用了 Hibernate,包括批量插入数百万条记录。您的问题不在于 Hibernate,而在于您使用它的方式。
最重要的是,不要将 Hibernate 用作持久状态管理器;将它用作原始 SQL 之上的薄层,您不会抱怨性能。
- 总是喜欢
StatelessSession
(它适用于你需要的一切,除了save
操作)`; - 永远不要使用延迟获取,对所有内容都使用显式连接;
- 永远不要获取整个对象,使用 SELECT 来获取你需要的东西;
- 在单个语句中尽可能多地获取,不惜一切代价避免 n+1 选择;
- 对于大型结果集,切勿使用
list
、使用iterate
或scroll
。
清单还在继续,但这是我此刻想出的。
至于您的直接问题,这取决于应用程序。如果它是一个 Spring 应用程序,那么你肯定会想要使用它的声明式事务管理。基本上,您只需放置几行 XML 配置,您的 DAO 代码中就会有一个开放的 DataSource 可供使用,而无需您进行任何管理。
如果你正在做一些更原始的事情,那么一定要使用连接池库,比如伟大的 BoneCP。您从它获取连接,然后将它们返回给它,同样没有显式管理。
最后,如果您真的想要一个简单、不安全且不可扩展的方法,那么您可以直接从 JDBC 驱动程序创建连接。这种方法实际上只适用于学校作业,即使在最小的具有生产价值的项目中也不推荐。
Hibernate 会话不仅仅是一个 JDBC 连接。它包含多个这样的连接(通常通过回收 JDBC 连接实例的 JDBC 连接池管理)、一组附加到所述会话并由所述会话和其他事物(缓存等)管理的实体。
删除 Hibernate 并仅使用 JDBC API 做所有事情将意味着不仅仅是用一个或多个 JDBC 连接替换 Hibernate Session 实例,然后将 Hibernate 代码复制到类似的 JDBC API 调用中。如果您只这样做,您将白白做很多工作,因为您将失去 Hibernate 的所有优势(更少冗长的代码、更高级别的抽象等),并且无法获得 JDBC 的优势(更少使用的堆内存,更少的方法调用(是的,即使使用 Hibernate 的 Javassist 魔法,在某些情况下这仍然会影响性能),对数据库交互的更细粒度的控制等)。
我的建议是首先真正研究您的应用程序存在的问题(显然是由于 Hibernate),至少对于主要问题,首先尝试看看您是否无法在不摆脱 Hibernate 的情况下对其进行优化。是的,Hibernate 可能会变得很重并且需要大量内存,但通常情况下,性能问题来自于对框架的不当使用(您确定要在一个查询中获取所有必要的关联实体,还是让 Hibernate后台隐藏连接或伪连接?您是在数据库端进行数据操作,还是在执行超出必要的通用 Hibernate 查询以获取数据后在 Java 代码中完成一些操作?等等。 )
如果您真的需要摆脱 Hibernate(也许您需要使用数据库的一些非常特定的功能,这些功能不是标准 SQL 并且 Hibernate 不允许您访问,例如 MySQL 通过自定义平面导入大量数据的能力-file 格式)然后确保您用它替换它(普通的 JDBC,或者可能是其他一些 ORM,如 EclipseLink)可以解决问题并以更高效的方式解决它。在开始重新拖拉代码之前做一个小的 POC 来测试这些可以为您节省大量时间。
虽然我强烈建议您听从 Marko 和 Shivan 的建议,但您可以使用 hibernate 来管理您的连接/会话/事务并执行您的 SQL 查询,而不会产生太多开销。
一个快速的谷歌搜索在从休眠会话中执行 SQL 时产生了这一点。
http://www.informit.com/guides/content.aspx?g=java&seqNum=575
虽然我同意前面的两个答案,但如果您真的想走直接执行 SQL 的道路,我会出于两个原因考虑这个选项。
1)您的会话已经到位。如果您没有休眠加载所有实体,我看不出休眠将如何产生那么多开销。
2)如果问题是速度,而不是我之前遇到的开销,您可以实现它以在您的问题区域快速执行本机 SQL 并保留所有休眠 ORM 好东西。
说了这么多,我还敦促您深入研究 hibernate 的文档。我已经将 hibernate 用于几个高性能的解决方案,并取得了巨大的成功。虽然一开始可能很难处理细微差别,但使用 hibernate(或至少遵循 JPA 标准的东西)的好处远远超过在可扩展性方面不这样做的成本。