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