对于我们的新产品重新设计,我们正在从 Java 中选择最佳框架。由于考虑为模型采用与数据库无关的方法,我们正在研究 Struts + Spring 与 iBATIS 或 Hibernate 之间的选项。请提出最好的建议,因为两者都提供持久性。
6 回答
iBATIS 和 Hibernate 是完全不同的野兽。
我倾向于这样看待它:如果您的视图更加以对象为中心,Hibernate 会更好地工作。但是,如果您认为更以数据库为中心,那么 iBATIS 是一个更强大的选择。
如果您完全控制了您的模式并且您没有极高的吞吐量要求,那么 Hibernate 可以很好地工作。对象模型提供了相当方便的代码,但代价是巨大的复杂性。
如果您正在处理需要编写相当复杂的 SQL 查询的“遗留”数据库模式,那么 iBATIS 可能会更好地工作。
HQL(Hibernate Query Language)是另一种你必须学习的语言,即便如此,你也可能会发现仍然需要编写 SQL 的情况。更重要的是,您可能会花半天时间找出 XML、属性、注释等的正确组合,以使 Hibernate 生成高性能的 SQL 查询。
这个问题没有普遍的“A 比 B 好”的答案。
考虑一下你想要达到的目标。通常,命令查询响应隔离 模型适用于复杂域。
原因是您通常尝试做以下两件事之一:
- 创建/更新/删除一些复杂的域实体
- 运行分析获取查询(即求和/聚合查询)
Hibernate适用于案例 1,允许您只创建一个 POJO 并持久化/更新它。它也可以快速执行此操作,除非您的域非常大。
myBatis非常适合您只需要答案的获取查询(案例 2)。Hibernate 将尝试加载整个对象图,您需要开始使用 LazyLoading 技巧调整查询以使其在大型域上工作。相反,如果您只想要一些分析 POJO 页面,则相同查询的 myBatis 实现将是微不足道的。
正因为如此,myBatis在 SELECTS 上比 Hibernate快。
这两种情况是您想要更改域数据的命令和您只想获取一些数据的响应之间的区别。
因此,请考虑这两种情况以及您的应用程序的功能。如果您有一个简单的域并且只是获取信息,请使用 myBatis。如果您有一个复杂的域并持久化实体,请使用 Hibernate。如果两者都做,请考虑采用混合方法。这就是我们在我们的项目中使用的,它有数千个实体来控制它。;)
ORM 与持久性框架
Hibernate 是将 Java 类映射到数据库表的对象关系映射框架 (ORM)。MyBatis 是持久化框架——不是 ORM。它将 SQL 语句映射到 Java 方法。
数据库架构
Hibernate 可以根据您的 Java 模型创建或验证数据库模式,而 MyBatis 没有此功能。当您使用内存数据库时,它也便于测试环境。相关讨论:
缓存
Hibernate 具有无法禁用的一级缓存。也就是说,如果你通过ORM查询item,然后用SQL直接删除它,它就留在缓存中。您可以显式清除缓存以从数据库中获取最新的结果。相关讨论:
乐观锁管理
乐观锁管理也有区别:
MyBatis 本身不支持乐观并发控制,这与带有 @Version 注解的 Hibernate/JPA 等 ORM 工具不同。
相关讨论:
延迟加载
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 Session执行的。它需要很好地理解如何实施适当的 Hibernate 会话管理策略来避免detached entity passed to persist
与 Hibernate 相关的其他现象。
有时,尝试理解底层 Hibernate 行为可能需要更多时间,而不是添加更多工作并为 myBatis 编写原始 SQL 语句。
级联
Hibernate 为对象图提供了级联、孤儿删除和其他功能,而它们在 myBatis 中不存在 - 要实现它们,您需要显式地编写 SQL 查询。
查询
在 myBatis 中,您将编写几乎简单的 SQL 查询。Hibernate 有多种形式的查询选项:SQL、HQL、Criteria API。当条件中有许多可选字段时,有时可能适合使用 Criteria API。它将提供更结构化的方法来形成查询,并可能避免相关的错误。
Cletus 在总结这种比较方面做得很好。当您控制数据模型并且更加以对象为中心时,Hibernate 运行良好,而当您需要与现有数据库集成并且更加以数据为中心时,iBATIS 运行良好。
我也认为 Hibernate 有更多的学习曲线。使用 iBATIS,很容易知道发生了什么,而 Hibernate 则发生了更多的“魔术”。换句话说,新手可能会发现 iBatis 更易于使用和理解。
但我并不是说你应该更喜欢 iBatis,iBatis 和 Hibernate 只是如上所述不同。
顺便说一句,如果您选择 Hibernate,也许可以考虑使用Hibernate Annotations提供的标准化 JPA 和 EJB 3.0 (JSR-220) 对象/关系映射注释。
Hibernate 是一个 ORM,这意味着(在最基本的层面上)它将 java 对象的实例映射到数据库表中的实际行。通常,对于通过 Hibernate 检索的 pojo:对这些 pojo 的任何操作和修改都将出现在数据库中。Hibernate 会在适当的时候生成并执行相关的 SQL。
Mybatis(在其最基本的层面上)只是一个用于拼凑和执行存储在 xml 文件中的 SQL 的工具。它不会将 Java 对象的实例映射到数据库表中的行,而是将 Java 方法映射到 SQL 语句,因此它不是 ORM。当然,它也可以返回 pojo,但它们不依赖于任何类型的持久性上下文。
两种工具都比上面描述的要多得多,但一种是 ORM,另一种不是。
我相信,使您能够选择使用哪一个的标准主要取决于您必须使用的数据库模型。
例如,想象一个庞大的架构,代表一些保险模型。开发人员需要检索数据,并以满足手头业务的方式与该数据交互。
开发人员来了,永远不会期望拥有必要的业务知识来手动编写所有 sql(Mybatis 需要)。Hibernate 适合这样的场景。
业务分析师定义数据模型、实体、关系和交互,以及他们的专业知识。Java 开发人员然后使用 Hibernate 来“走模型”。业务开发人员可以很快变得非常高效,而无需编写复杂的容易出错的 sql 以在非常复杂的模式上运行。
根据我的经验,Hibernate 和 Mybatis 经常在同一个项目中使用。
使用 Hibernate 的地方
- 常规 CRUD 功能
- “走”“领域对象”关系模型
- 会话管理
以及 Mybatis 被用于什么地方
- 即席查询
- 启动(并与之交互)存储过程
- 支持非常具体或复杂的查询
- 支持复杂的搜索查询,其中搜索条件是动态的,以及结果分页
如果您已经在使用 Spring,我会从 Spring JDBC 开始,而不是直接使用 Hibernate 或 iBatis。如果您根据接口编写持久层,那么在您掌握了 Hibernate 或 iBatis 之后切换实现应该没有问题。
没有理由必须做出“全有或全无”的决定。使用最适合您的情况。