Hibernate与iBATIS

对于我们的新产品重新devise,我们正在从Java中select最好的框架。 考虑到模型的数据库不可知的方法,我们正在研究Struts + Spring与iBATIS或Hibernate之间的选项。 请build议这是最好的,因为两者都提供持久性。

Ibatis和Hibernate是完全不同的野兽。

我倾向于这样看的方式是:如果您的视图更加以对象为中心的话,Hibernate会更好。 如果你认为更多的是以数据库为中心的话,那么Ibatis是一个更强的select。

如果你完全控制你的模式,并且你没有一个非常高的吞吐量要求,那么Hibernate可以很好地工作。 对象模型使得代码相当方便,但是代价非常高。

如果您正在处理需要编写相当复杂的SQL查询的“遗留”数据库模式,那么Ibatis可能会更好地工作。

HQL(Hibernate查询语言)是另一种你必须学习的语言,即使这样你也许会发现你仍然需要编写SQL的情况。 更重要的是,你可能会花半天的时间搞清楚XML,属性,注释等的正确组合,让Hibernate生成一个高性能的SQL查询。

这个问题没有普遍的“A比B好”的答案。

考虑你想要达到的目标。 通常, 命令查询响应分离模型对于复杂的域很有效。

原因是你试图做两件事情之一:

  1. 创build/更新/删除一些复杂的域实体
  2. 运行分析抓取查询(即求和/聚合查询)

Hibernate适用于案例1,允许您只做一个POJO并坚持/更新它。 它也做到这一点很快,除非你的域名相当大。

myBatis非常适合查询(情况2),您只需要一个答案。 Hibernate会试图加载整个对象图,你需要开始使用LazyLoading技巧来调整查询,以保持它在一个大的域上工作。 相反,如果你只是想要一些分析POJO页面,相同查询的myBatis实现将是微不足道的。

因此,myBatis在SELECTS上比Hibernate快。

这两种情况是您要更改域数据的命令和您只想获取某些数据的响应之间的区别。

所以,考虑这两种情况,你的应用程序做了什么。 如果您有一个简单的域,只需获取信息,请使用myBatis。 如果你有一个复杂的域和坚持的实体,使用Hibernate。 如果你们两个都做,就考虑采用混合方法。 这就是我们在拥有数千个实体的项目上使用它来控制它。 ;)

Cletus在总结这个比较方面做了很多工作。 当你控制数据模型时,Hibernate可以很好地工作,并且更加以对象为中心,而当你需要与现有数据库集成并且更加以数据为中心的时候,iBATIS运行良好。

另外我认为Hibernate有更多的学习曲线。 使用iBATIS,知道发生了什么很容易,而Hibernate会发生更多的“魔法”。 换句话说,新手可能会发现iBatis更易于使用和理解。

但是我并不是说你应该更喜欢iBatis,而iBatis和Hibernate只是和上面所说的不同。

顺便说一下,如果你使用Hibernate,可以考虑使用由Hibernate Annotations提供的标准化的JPA和EJB 3.0(JSR-220)对象/关系映射注释。

如果你已经在使用Spring,我将从Spring JDBC开始,而不是直接进入Hibernate或者iBatis。 如果你用接口编写你的持久化层,那么在你把Hibernate或iBatis带到你的系统之后,你应该没有问题。

没有理由为什么它必须是一个“全部或没有”的决定。 使用最适合你的情况。

Hibernate是一个ORM,意思是(在最基本的层次上),它将Java对象的实例映射到数据库表中的实际行。 一般来说,对于通过Hibernate检索的pojo:对这些pojo的任何操作和修改都将出现在数据库中。 Hibernate会在适当的时候生成和执行相关的SQL。

Mybatis(最基本的级别)只是一个拼接和执行存储在xml文件中的SQL的工具。 它不会将Java对象的实例映射到数据库表中的行,而是将Java方法映射到SQL语句,因此它不是一个ORM。 它当然也可以返回POJO的,但是它们不受任何types的持久性背景的束缚。

这两种工具都比上面描述的要多得多,但是其中一个是ORM,一个不是。

我相信,使您能够select使用哪一个的标准关键取决于您必须使用的数据库模型。

例如,想象一个庞大的模式,代表一些保险模式。 开发人员需要检索数据,并以符合当前业务的方式与数据进行交互。

开发人员来吧,永远不会被期望拥有必要的商业知识手写所有的SQL(Mybatis需要)。 Hibernate会适合这样的场景。

业务分析师定义数据模型,实体,关系和交互,以及他们的专业知识。 Java开发人员然后使用Hibernate来“走模型”。 业务开发人员可以快速提高生产力,而不需要编写复杂的容易出错的SQL来运行在一个非常复杂的模式上。

在我的发现中,Hibernate和Mybatis都在同一个项目中经常使用。

在哪里使用Hibernate

  • 一般的CRUDfunction
  • “走”'域对象'关系模型
  • 会话pipe理

以及Mybatis正在使用的地方

  • 即席查询
  • 启动(并与之交互)存储过程
  • 支持非常具体或错综复杂的查询
  • 支持复杂的search查询,其中search条件是dynamic的,并且分页结果

ORM与持久性框架

Hibernate是将Java类映射到数据库表的对象关系映射框架(ORM)。 MyBatis是持久性框架 – 而不是ORM。 它将SQL语句映射到Java方法。

数据库架构

Hibernate可以根据你的Java模型创build数据库模式,而MyBatis没有这个特性。 相关讨论:

  • MyBatis可以创build数据库模式吗?

高速caching

hibernate有一级caching,这是不可能禁用。 这意味着如果您通过ORM查询项目,然后直接使用SQL删除项目,它将保留在caching中。 您可以显式清除caching以从数据库获取最新的结果。 相关讨论:

  • Jpa&Hibernate是否加载在数据库中asynchronous更改的数据?
  • 什么是Hibernate中的一级和二级caching?

乐观锁pipe理

乐观锁pipe理也有不同之处:

与带有@Version注释的Hibernate / JPA等ORM工具不同,MyBatis本身不支持乐观并发控制。

相关讨论:

  • 乐观的并发控制
  • 如何通过iBatis防止更新中的并发问题

延迟加载

Hibernate将尝试加载整个对象图,但标记为延迟加载的对象除外。 myBatis将根据SQL查询加载数据。 延迟加载可能会提高性能,但如果与<property name="hibernate.enable_lazy_load_no_trans" value="true" />属性一起使用,可能会导致连接泄漏。 相关讨论:

  • org.hibernate.LazyInitializationException – 无法初始化代理 – 没有会话
  • 用hibernate.enable_lazy_load_no_trans解决Hibernate的Lazy-Init问题

hibernate会话pipe理

像保存,更新或删除的实体操作通过Hibernate Session执行。 它需要很好的理解如何实现适当的Hibernate会话pipe理策略,以避免被detached entity passed to persist和其他与Hibernate相关的现象。

有时可能需要更多的时间才能理解潜在的Hibernate行为,而不是增加一点点工作,并为myBatis编写原始SQL语句。

级联

Hibernate为对象图提供级联,孤立删除和其他function,但它们不出现在myBatis中 – 要实现它们,您需要明确编写SQL查询。

查询

在myBatis中,你会写几乎原始的SQL查询。 Hibernate有多个选项来形成查询:SQL,HQL,Criteria API。 有时,如果标准中有许多可选字段,则可能适合使用Criteria API。 它将提供更加结构化的方法来形成查询,并避免相关的错误。