近期在研究亚信软件CMC部门的底层框架代码,发现CMC部门在与数据库交互方面用的不是强大的Hibernate或iBatis,而是采用了JDBC(对JDBC的一种轻封装)。经过1年时间的使用,发现这种对JDBC封装的框架确实有他的好处。这里对Hibernate与JDBC的优劣做一个对比。
本文将通过内存消耗、运行效率和开发效率三个方面作对比
- 内存消耗:采用JDBC的架构是最省内存的。Hibernate的架构就消耗内存略大
- 运行效率:如果JDBC的代码写的非常优化,那么JDBC架构运行效率是最好的,当然这需要开发员非常精通JDBC,运用Batch语句,调整PreparedStatement的Batch Size等参数,以及必要情况下采用结果集的cache等。当然一般情况下,很少有开发员很难做到这一点。因此配置相对简单的Hibernate表现出的运行效率最快
- 开发效率:在大型项目中,特别是对象关系映射很复杂的情况下Hibernate的开发效率高的惊人。JDBC好写比较复杂的SQL语句,而导致开发效率略低于Hibernate
但是Hibernate太灵活了,相同的问题可能会有几套甚至十几套设计方案,导致选择太多,等于纠结(广告语,请自动屏蔽)。光主键生成都有7-8中方案供你选择。集合属性可以用list、set,还可以用Bag,到底哪个效率高?比较纠结。查询可以用iterator,可以用list,这哪个比较好,有什么区别?要花时间去比较。对于一个表,可以选择单一映射一个对象,也可以映射成父子对象,哪个方案比较好?等等诸如此类的问题,导致非深入Hibernate的开发者可能会花费很多时间来比较各种性能或者选择使用哪种方案。
JDBC与Hibernate在性能上相比,JDBC灵活性有优势。而Hibernate在于易学、易用有优势。当用到复杂的多表联查或复杂的数据库操作时,JDBC有优势。
JDBC与Hibernate读取性能比较:
- JDBC仍然是最快的访问方式,CRUD操作都是最快的
- Hibernate使用uuid构造主键,性能会稍有损失
- 读取性能上,Hibernate的Iterator速度非常缓慢,因为他只存储主键到内存,每次查询还要再与数据库交互。Hibernate的List速度与JDBC差不多,都是一次性把数据读完,但是非常消耗时间,而且Hibernate的List消耗的内存几乎是JDBC消耗内存的一倍。
- 精心编写的JDBC无论如何都是最快的
- Hibernate的List和Iterator适用场合不同,不存在孰优孰略的问题
Hibernate的劣势:
- 对JDBC的大量封装导致了失去了对SQL的控制,如果适用native sql来调用数据库相关的sql,又影响了hibernate的性能和可移植性。而且Hibernate很多地方不灵活,难于优化,尤其对于一些复杂的关联查询时,Hibernate提供的功能远不及JDBC性能高
- Hibernate没有专门的批处理机制,如果要批量更新或者批量插入,还需要显示的flush,clear之类的操作,性能不如JDBC
- 相对于JDBC,hibernate要消耗更多内存,因为它每次的数据库操作都要数据和对象的转换/封装。查询一条数据就要创建一个或多个对象。
- Hibernate提供了很多的好处,但这些好处本身也是陷阱。有时程序本身没有问题却达不到预期效果,这是一件令人抓狂的事情。