【问题标题】:converting sessions in hibernate to plein JDBC connections将休眠中的会话转换为 plein JDBC 连接
【发布时间】:2012-10-25 23:57:21
【问题描述】:

为了克服使用 hibernate 产生的开销,我正在从 hibernate 转换回普通 JDBC。我想知道如何处理与 hibernate 相关的会话。我应该如何转换回普通 JDBC,以便我的所有会话替换为 JDBC 连接。如果我认为用连接替换会话会转换回普通 JDBC 的想法有误,请告诉我,因为我不精通这些概念并且不知道我是否正确方式。

【问题讨论】:

  • 查询呢?您使用的是 HQL 还是 Criteria API?您还必须转换所有查询。
  • 是的,我已转换所有查询。我已将所有 HQL 替换为 SQL

标签: java hibernate session jdbc


【解决方案1】:

我在高性能任务中广泛使用了 Hibernate,包括批量插入数百万条记录。您的问题不在于 Hibernate,而在于您使用它的方式。

最重要的是,不要将 Hibernate 用作持久状态管理器;将其用作原始 SQL 之上的薄层,您不会抱怨性能。

  1. 总是更喜欢StatelessSession(它适用于您需要的一切,除了save 操作)`;
  2. 永远不要使用延迟获取,对所有内容都使用显式连接;
  3. 永远不要获取整个对象,使用 SELECT 准确获取您需要的内容;
  4. 在单个语句中尽可能多地获取,不惜一切代价避免 n+1 次选择;
  5. 对于大型结果集,切勿使用list,使用iteratescroll

名单还在继续,但这是我此刻想出的。

就您的直接问题而言,这取决于应用程序。如果它是一个 Spring 应用程序,那么你肯定会想要使用它的声明式事务管理。基本上,您只需放置几行 XML 配置,您的 DAO 代码中就会有一个开放的 DataSource 可供使用,而无需您进行任何管理。

如果您正在做一些更原始的事情,那么一定要使用连接池库,例如伟大的 BoneCP。您从它获取连接,然后将它们返回给它,同样没有显式管理。

最后,如果您真的想要一个简单、不安全且不可扩展的方法,那么您可以直接从 JDBC 驱动程序创建连接。这种方法实际上只适用于学校作业,即使在最小的具有生产价值的项目中也不推荐。

【讨论】:

  • 感谢 Marko 的回复,但我是企业界的初学者,我的 TL 决定转换回普通 JDBC。我的数据库不是很大,它不会不断变化,因此选择了 Hibernate 或其他 ORM。我几乎用 SQL 替换了所有 HQL,现在卡在会话中。请帮忙。
【解决方案2】:

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 通过以下方式导入大量数据的能力)一个自定义的平面文件格式)然后确保你用它替换它(普通的 JDBC,或者可能像 EclipseLink 之类的其他 ORM)可以解决问题并以更高效的方式解决它。在开始重新编写代码之前做一个小的 POC 来测试这些可以为您节省大量时间。

【讨论】:

    【解决方案3】:

    虽然我强烈建议您听从 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 标准的东西)的好处远远超过在可扩展性方面不这样做的成本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-29
      • 2012-03-17
      • 1970-01-01
      • 2015-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-16
      相关资源
      最近更新 更多