Hibernate与Mybatis比较

前言

之前对hibernate有过详细的介绍,还整理成了专栏,但现在并非是hibernate一家独大,还有一种ORM框架与hibernate平分天下,本篇文章就对两者做个详细的对比介绍。
在开发一个项目之前,架构的技术选型对于项目的是否成功,是否高效,是否稳健至关重要。所以我们不仅要了解某一种技术的原理和实现,还要知道各种相似技术之间的差异,根据开发环境选择合适的技术。而最为ORM框架中的翘楚,我们往往需要在hibernate和Mybatis中择优选择。

Hibernate与Mybatis

Hibernate 是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分。 Mybatis 是另外一种优秀的O/R mapping框架。目前属于apache的一个子项目。

简介

Hibernate:
Hibernate对数据库结构提供了较为完整的封装,Hibernate的O/R Mapping实现了POJO 和数据库表之间的映射,以及SQL 的自动生成和执行。开发人员甚至对sql不太熟悉也可以开发,只不过这样要求开发人员对Hibernate有深刻的理解。

Mybatis
Mybatis是Ibatis的进化版。主要着力点在于 POJO 与 SQL 之间的映射关系。然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定POJO 。相对Hibernate“O/R”而言,Mybatis 是一种“Sql Mapping”的ORM实现。也有人称之为“半自动化的ORM框架”。

开发要求

1.难易度

Hibernate真正掌握要比Mybatis难些,Hibernate比Mybatis是一个重量级的ORM框架,封装比较完善。相对的,Mybatis虽然相对简陋,但是简单容易上手。个人觉得,为了更好的理解ORM框架的原理还是好好学学Hibernate,这样对使用Mybatis也有帮助。

2.工作量
Hibernate和Mybatis都有相应的代码生成工具,可以生成简单的Dao层方法。虽然Hibernate工具相对于Mybatis来说比较多,但是Mybatis的工具也足够使用。
针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。但是需要处理好映射和加载的问题。而Mybatis则相对灵活一些,可以自定义一些查询。

系统调优

调优方案:
1. 制定合理的缓存策略;
2. 尽量使用延迟加载特性;
3. 采用合理的Session管理机制;
4. 使用批量抓取,设定合理的批处理参数;
5. 进行合理的O/R映射设计

在Session管理机制,缓存策略,O/R映射设计方面,Hibernate和Mybatis基本上是一致的,但在抓取策略Hibernate对实体关联对象的抓取有着良好的机制。对于每一个关联关系都可以详细地设置是否延迟加载,并且提供关联抓取、查询抓取、子查询抓取、批量抓取四种模式。 它是详细配置和处理的。
而Mybatis的延迟加载是全局配置的。

SQL优化

Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。
MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。

数据库扩展性

Mybatis由于所有SQL都是依赖数据库书写的,所以扩展性,迁移性比较差。
Hibernate与数据库具体的关联都在XML中,所以HQL对具体是用什么数据库并不是很关心。

缓存机制

Hibernate
Hibernate的缓存有一级缓存Session级和二级缓存SessionFactory级。我们在Hibenrnate之缓存(一)Hibenrnate之缓存(二)中有详细的讲解。

Mybatis
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。
默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:
字面上看就是这样。这个简单语句的效果如下:

  1. 映射语句文件中的所有 select 语句将会被缓存。
  2. 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
  3. 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
  4. 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
  5. 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
  6. 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

所有的这些属性都可以通过缓存元素的属性来修改。
比如:

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会 导致冲突。可用的收回策略有, 默认的是 LRU:
1. LRU – 最近最少使用的:移除最长时间不被使用的对象。
2. FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3. SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4. WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可用内存资源数目。默认值是1024。
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓 存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是 false。

相同点:
Hibernate和Mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通过实现你自己的缓存或为其他第三方缓存方案,创建适配器来完全覆盖缓存行为。

不同点:
Hibernate的二级缓存配置在SessionFactory生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置是那种缓存。
MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。

两者比较:
因为Hibernate对查询对象有着良好的管理机制,用户无需关心SQL。所以在使用二级缓存时如果出现脏数据,系统会报出错误并提示。
而MyBatis在这一方面,使用二级缓存时需要特别小心。如果不能完全确定数据更新操作的波及范围,避免Cache的盲目使用。否则,脏数据的出现会给系统的正常运行带来很大的隐患。

对比总结

两者相同点

  1. Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命周期都是差不多的。
  2. Hibernate和MyBatis都支持JDBC和JTA事务处理。
  3. Hibernate和MyBatis,可以使用第三方缓存。

Mybatis优势

• MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
• MyBatis容易掌握,而Hibernate门槛较高。

Hibernate优势

• Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。
• Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要方便。
• Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。


Mybatis:小巧、方便、高效、简单、直接、半自动化

Hibernate:强大、方便、高效、复杂、间接、全自动化

猜你喜欢

转载自blog.csdn.net/wj8023/article/details/49516293