Hibernate、iBatis、Java EE 或其他 Java ORM 工具
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/716532/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate, iBatis, Java EE or other Java ORM tool
提问by Kevin Williams
We're in the process of planning a large, enterprise application. We're focusing our efforts on evaluating hibernate after experiencing the pains of J2EE.
我们正在规划大型企业应用程序。在经历了 J2EE 的痛苦之后,我们将精力集中在评估 hibernate 上。
It looks like the new Java EE API is simpler. I've also read some good things about Hibernate and iBatis. Our team has little experience with any of the frameworks.
看起来新的 Java EE API 更简单。我还阅读了一些关于 Hibernate 和 iBatis 的好文章。我们的团队对任何框架都几乎没有经验。
There are 5 main comparisong points I'd like to determine
我想确定 5 个主要的比较点
- Learning Curve/Ease of Use
- Productivity
- Maintainability/Stability
- Performance/Scalability
- Ease of Troubleshooting
- 学习曲线/易用性
- 生产率
- 可维护性/稳定性
- 性能/可扩展性
- 易于故障排除
If you were to manage a team of ~6 developers with J2EE experience which ORM tool would you use and why?
如果您要管理一个由约 6 名具有 J2EE 经验的开发人员组成的团队,您会使用哪种 ORM 工具?为什么?
采纳答案by cletus
Let me take a crack at this. First of, I've written some on this subject in Using an ORM or plain SQL?. Specifically to address your points:
让我来看看这个。首先,我在Using an ORM or plain SQL? 中写了一些关于这个主题的文章。. 专门解决您的问题:
Learning Curve/Ease of Use
学习曲线/易用性
Ibatis is about SQL. If you know SQL the learning curve for ibatis is trivial. Ibatis does some things on top of SQL such as:
Ibatis 是关于 SQL 的。如果您了解 SQL,那么 ibatis 的学习曲线是微不足道的。Ibatis 在 SQL 之上做了一些事情,例如:
- group by;
- discriminated types; and
- dynamic SQL.
- 通过...分组;
- 受歧视的类型;和
- 动态 SQL。
that you'll still need to learn but the biggest hurdle is SQL.
您仍然需要学习,但最大的障碍是 SQL。
JPA (which includes Hibernate) on the other hand tries to distance itself from SQL and present things in an object rather than a relational way. As Joel points out however, abstractions are leakyand JPA is no exception. To do JPA you'll still need to know about relational models, SQL, performance tuning of queries and so forth.
另一方面,JPA(包括 Hibernate)试图与 SQL 保持距离,并以对象而不是关系方式呈现事物。然而,正如 Joel 指出的那样,抽象是有漏洞的,JPA 也不例外。要进行 JPA,您仍然需要了解关系模型、SQL、查询的性能调整等。
Whereas Ibatis will simply having you apply the SQL you know or are learning, JPA will require you to know something else: how to configure it (either XML or annotations). By this I mean figuring out that foreign key relationships are a relationship (one-to-one, one-to-many or many-to-many) of some kind, the type mapping, etc.
Ibatis 只会让您应用您知道或正在学习的 SQL,而 JPA 会要求您知道其他东西:如何配置它(XML 或注释)。我的意思是弄清楚外键关系是某种关系(一对一、一对多或多对多),类型映射等。
If you know SQL I would say the barrier to learning JPA is actually higher. If you don't, it's more of a mixed result with JPA allowing you to effectively defer learning SQL for a time (but it doesn't put it off indefinitely).
如果您了解 SQL,我会说学习 JPA 的障碍实际上更高。如果你不这样做,那么 JPA 的结果更像是一个混合结果,允许你有效地推迟学习 SQL 一段时间(但它不会无限期地推迟)。
With JPA once you setup your entities and their relationships then other developers can simply use them and don't need to learn everything about configuring JPA. This could be an advantage but a developer will still need to know about entity managers, transaction management, managed vs unmanaged objects and so on.
使用 JPA,一旦您设置了实体及其关系,其他开发人员就可以简单地使用它们,而无需了解有关配置 JPA 的所有知识。这可能是一个优势,但开发人员仍然需要了解实体管理器、事务管理、托管与非托管对象等。
It's worth noting that JPA also has its own query language (JPA-SQL), which you will need to learn whether or not you know SQL. You will find situations where JPA-SQL just can't do things that SQL can.
值得注意的是,JPA 也有自己的查询语言(JPA-SQL),无论您是否了解 SQL,您都需要了解它。您会发现 JPA-SQL 不能做 SQL 可以做的事情的情况。
Productivity
生产率
This is a hard one to judge. Personally I think I'm more productive in ibatis but I'm also really comfortable with SQL. Some will argue they're way more productive with Hibernate but this is possibly due--at least in part--to unfamiliarity with SQL.
这是一个很难判断的。就我个人而言,我认为我在 ibatis 中的效率更高,但我对 SQL 也非常熟悉。有些人会争辩说,他们使用 Hibernate 的效率更高,但这可能是由于——至少部分原因——不熟悉 SQL。
Also the productivity with JPA is deceptive because you will occasionally come across a problem with your data model or queries that takes you a half a day to a day to solve as you turn up logging and watch what SQL your JPA provider is producing and then working out the combination of settings and calls to get it to produce something that's both correct and performant.
此外,JPA 的生产力具有欺骗性,因为您偶尔会遇到数据模型或查询的问题,当您打开日志记录并观察您的 JPA 提供者正在生成和工作的 SQL 时,这些问题需要您花半天到一天的时间来解决去掉设置和调用的组合,让它产生既正确又高效的东西。
You just don't have this kind of problem with Ibatis because you've written the SQL yourself. You test it by running the SQL inside PL/SQL Developer, SQL Server Management Studio, Navicat for MySQL or whatever. After the query is right, all you're doing is mapping inputs and outputs.
你只是在 Ibatis 上没有这种问题,因为你自己写了 SQL。您可以通过在 PL/SQL Developer、SQL Server Management Studio、Navicat for MySQL 或其他任何东西中运行 SQL 来测试它。查询正确后,您要做的就是映射输入和输出。
Also I found JPA-QL to be more awkward than pure SQL. You need separate tools to just run a JPA-QL query to see the results and it's something more you have to learn. I actually found this whole part of JPA rather awkward and unwieldy although some people love it.
我还发现 JPA-QL 比纯 SQL 更笨拙。您需要单独的工具来运行 JPA-QL 查询以查看结果,这是您需要学习的更多内容。我实际上发现 JPA 的整个部分相当笨拙和笨拙,尽管有些人喜欢它。
Maintainability/Stability
可维护性/稳定性
The danger with Ibatis here is proliferation meaning your dev team may just keep adding value objects and queries as they need them rather than looking for reuse whereas JPA has one entitty per table and once you have that entity, that's it. Named queries tend to go on that entity so are hard to miss. Ad-hoc queries can still be repeated but I think it's less of a potential problem.
Ibatis 的危险在于扩散,这意味着您的开发团队可能只是在需要时不断添加值对象和查询,而不是寻求重用,而 JPA 每个表只有一个实体,一旦您拥有该实体,就是这样。命名查询倾向于在该实体上进行,因此很难错过。临时查询仍然可以重复,但我认为这不是一个潜在的问题。
That comes at the cost of rigidity however. Often in an application you will need bits and pieces of data from different tables. With SQL it's easy because you can write a single query (or a small number of queries) to get all that data in one hit and put it in a custom value object just for that purpose.
然而,这是以刚性为代价的。通常在应用程序中,您需要来自不同表的零碎数据。使用 SQL 很容易,因为您可以编写单个查询(或少量查询)以一次性获取所有数据,并将其放入自定义值对象中,仅用于此目的。
With JPA you are moving up that logic into your business layer. Entities are basically all or nothing. Now that's not strictly true. Various JPA providers will allow you to partially load entities and so forth but even there you're talking about the same discrete entitites. If you need data from 4 tables you either need 4 entities or you need to combine the data you want into some kind of custom value object in the business or presentation layer.
使用 JPA,您可以将该逻辑向上移动到您的业务层。实体基本上是全有或全无。现在这不是严格正确的。各种 JPA 提供程序将允许您部分加载实体等等,但即使在那里您谈论的是相同的离散实体。如果您需要来自 4 个表的数据,您要么需要 4 个实体,要么需要将所需的数据组合到业务或表示层中的某种自定义值对象中。
One other thing I like about ibatis is that all your SQL is external (in XML files). Some will cite this is as a disadvantage but not me. You can then find uses of a table and/or column relatively easy by searching your XML files. With SQL embedded in code (or where there is no SQL at all) it can be a lot harder to find. You can also cut and paste SQL into a database tool and run it. I can't overstate enough how many times this has been useful to me over the years.
我喜欢 ibatis 的另一件事是您的所有 SQL 都是外部的(在 XML 文件中)。有些人会引用这是一个缺点,但不是我。然后,您可以通过搜索 XML 文件相对容易地找到表和/或列的用途。将 SQL 嵌入到代码中(或者根本没有 SQL 的地方)可能会更难找到。您还可以将 SQL 剪切并粘贴到数据库工具中并运行它。多年来,这对我有用过多少次,我怎么夸大都不为过。
Performance/Scalability
性能/可扩展性
Here I think ibatis wins hands down. It's straight SQL and low cost. By its nature JPA simply won't be able to manage the same level of latency or throughput. Now what JPA has going for it is that latency and throughput are only rarely problems. High performance systems however do exist and will tend to disfavour more heavyweight solutions like JPA.
在这里,我认为 ibatis 获胜。它是直接的 SQL 且成本低。就其性质而言,JPA 根本无法管理相同级别的延迟或吞吐量。现在 JPA 的目标是延迟和吞吐量很少成为问题。然而,高性能系统确实存在,并且倾向于不喜欢像 JPA 这样的重量级解决方案。
Plus with ibatis you can write a query that returns exactly the data you want with the exact columns that you need. Fundamentally there's no way JPA can beat (or even match) that when it's returning discrete entities.
加上 ibatis,您可以编写一个查询,该查询使用您需要的确切列准确返回您想要的数据。从根本上说,当 JPA 返回离散实体时,它无法击败(甚至匹配)它。
Ease of Troubleshooting
易于故障排除
I think this one is a win for Ibatis too. Like I mentioned above, with JPA you will sometimes spend half a day getting a query or entity produce the SQL you want or diagnosing a problem where a transaction fails because the entity manager tried to persist an unmanaged object (which could be part of a batch job where you've committed a lot of work so it might be nontrivial to find).
我认为这也是 Ibatis 的胜利。就像我上面提到的那样,使用 JPA,您有时会花费半天时间来获取查询或实体生成您想要的 SQL 或诊断事务失败的问题,因为实体管理器试图持久化一个非托管对象(它可能是批处理的一部分)您已经完成了大量工作的工作,因此可能很难找到)。
Both of them will fail if you try to use a table or column that doesn't exist, which is good.
如果您尝试使用不存在的表或列,它们都会失败,这很好。
Other criteria
其他标准
Now you didn't mention portability as one of your requirements (meaning moving between database vendors). It's worth noting that here JPA has the advantage. The annotations are less portable than, say, Hibernate XML (eg standard JPA annotations don't have an equivalent for Hibernate's "native" ID type) but both of them are more portable than ibatis / SQL.
现在您没有提到可移植性是您的要求之一(意味着在数据库供应商之间移动)。值得注意的是,这里JPA有优势。注释的可移植性不如 Hibernate XML(例如,标准 JPA 注释没有 Hibernate 的“本机”ID 类型的等效项),但它们都比 ibatis/SQL 更可移植。
Also I've seen JPA / Hibernate used as a form of portable DDL, meaning you run a small Java program that creates the database schema from JPA configuration. With ibatis you'll need a script for each supported database.
此外,我还看到 JPA/Hibernate 用作一种可移植的 DDL,这意味着您运行一个小型 Java 程序,该程序从 JPA 配置创建数据库模式。使用 ibatis,您需要为每个受支持的数据库编写一个脚本。
The downside of portability is that JPA is, in some ways, lowest common denominator, meaning the supported behaviour is largely the common supported behaviour across a wide range of database vendors. If you want to use Oracle Analytics in ibatis, no problem. In JPA? Well, that's a problem.
可移植性的缺点是 JPA 在某些方面是最低公分母,这意味着支持的行为在很大程度上是广泛的数据库供应商共同支持的行为。如果你想在ibatis中使用Oracle Analytics,没问题。在 JPA 中?嗯,这是个问题。
回答by StaxMan
A simplistic rule of thumb between iBatis and Hibernate is that if you want more SQL/relational view of the world, iBatis is better fit; and for more complex inheritance chain, and less direct view to SQL, Hibernate. Both are widely used and solid good frameworks. So I think both would probably work well. Perhaps read a tutorial for both, see if one sounds better than the other, and just pick one.
iBatis 和 Hibernate 之间的一个简单的经验法则是,如果你想要更多的 SQL/关系视图,iBatis 更适合;而对于更复杂的继承链,以及较少直接查看SQL的Hibernate。两者都被广泛使用并且是可靠的良好框架。所以我认为两者都可能运作良好。也许阅读两者的教程,看看一个听起来是否比另一个更好,然后选择一个。
Of things you list, I don't think performance is very different -- bottleneck will almost invariably be the database, not framework. For other things I think different developers would prefer one or the other, i.e. there's no commonly accepted priority (for iBatis vs Hibernate).
在您列出的内容中,我认为性能并没有太大的不同——瓶颈几乎总是数据库,而不是框架。对于其他事情,我认为不同的开发人员会更喜欢其中一个,即没有普遍接受的优先级(对于 iBatis 与 Hibernate)。
回答by Yakov Fain
Have you tried to answer WHY even use an ORM tool before deciding which one to use? If you have people on your team who know SQL, see stick to JDBC.
在决定使用哪个工具之前,您是否尝试过回答为什么甚至使用 ORM 工具?如果您的团队中有人了解 SQL,请参阅坚持使用 JDBC。
回答by cherouvim
Go with hibernate. Your project will definitely grow larger later on and the investment (on learning hibernate) will pay off one way or another.
去冬眠。您的项目以后肯定会变得更大,并且投资(在学习休眠方面)将以一种或另一种方式获得回报。
回答by duffymo
If you don't have a good object model, I don't see the benefit of Hibernate. You certainly have the "relational" in ORM, since you have a relational database, but the "object" is key. No objects, no ORM. I think a 1:1 mapping between objects and tables, without richer object behavior, does not justify ORM. Stick with JDBC or iBatis if that's your situation.
如果您没有一个好的对象模型,我就看不到 Hibernate 的好处。您肯定在 ORM 中有“关系”,因为您有一个关系数据库,但“对象”是关键。没有对象,没有 ORM。我认为对象和表之间的 1:1 映射,没有更丰富的对象行为,并不能证明 ORM 是合理的。如果那是您的情况,请坚持使用 JDBC 或 iBatis。
回答by Edward Q. Bridges
Which solution you go with also is dependent on how compliant you choose (or are required) to be with the Java EE spec. JPA is "the standard" for data access in Java EE systems, so if you're particular about adhering to that, you should use it (with some caveats).
您采用哪种解决方案还取决于您选择(或要求)符合 Java EE 规范的程度。JPA 是 Java EE 系统中数据访问的“标准”,因此如果您特别注意遵守该标准,则应该使用它(有一些注意事项)。
JPA is a standardization of object-relational mapping systems. As such, it does not provide an implementation, it simply defines a standardized approach. Hibernate Entity Manager is one such implementation.
JPA 是对象关系映射系统的标准化。因此,它不提供实现,它只是定义了一种标准化的方法。Hibernate Entity Manager 就是这样一种实现。
Since JPA is a standard across multiple vendors and since it is still fairly new, it lacks some more esoteric functionality that is valuable in some use cases (for example, a Criteria API for generating dynamic SQL). If you go with JPA plan on situations where you'll nee to use Hibernate directly, or even JDBC directly. For situations such as this, a generic DAO pattern is very useful; you can modify this one: Generic Data Access Objectsfor use in JPA & JDBC quite easily.
由于 JPA 是跨多个供应商的标准,而且它仍然是相当新的,因此它缺少一些在某些用例中很有价值的更深奥的功能(例如,用于生成动态 SQL 的 Criteria API)。如果您在需要直接使用 Hibernate 甚至直接使用 JDBC 的情况下使用 JPA 计划。对于这种情况,通用 DAO 模式非常有用;您可以很容易地修改这个:用于在 JPA 和 JDBC 中使用的通用数据访问对象。
JPA has some difficult restrictions (particularly if you're used to Hibernate), and imposes certain approaches on you that are difficult for developers who are more used to writing straight JDBC. If you are championing this as an approach, be sure to do your homework about the pros vs. cons of ORM vs. JDBC.
JPA 有一些困难的限制(特别是如果您习惯了 Hibernate),并且强加给您的某些方法对于更习惯于直接编写 JDBC 的开发人员来说是困难的。如果您支持这种方法,请务必做好功课,了解 ORM 与 JDBC 的优缺点。
If you go with JPA, once you've reached the learning curve it will pay off in terms of simple development (particularly if you properly implement the abovementioned DAO pattern), but also in getting multi-tiered caching of query results. If done properly (a big "if", I know), I have seen this provide handsome benefits.
如果您使用 JPA,一旦您达到学习曲线,它将在简单开发(特别是如果您正确实现上述 DAO 模式的情况下)以及获得查询结果的多层缓存方面获得回报。如果做得好(我知道这是一个很大的“如果”),我已经看到这提供了可观的好处。
Lastly, if you have a legacy data model that you have little flexibility with, Hibernate (and JPA) will give you more headaches than maybe worth. For example:
最后,如果你有一个遗留数据模型,你几乎没有灵活性,Hibernate(和 JPA)会给你带来更多的麻烦。例如:
- If the database does not have candidate primary keys (for effective hashCode & equals implementations) you will need to do upfront analysis on which columns define a row uniquely -- maybe simple, maybe complex depending on the complexity of your schema;
- If you're unable to add version or timestamp columns, you lose Hibernate's ability to do optimistic locking, and end up having to query before updating.
- 如果数据库没有候选主键(对于有效的 hashCode 和 equals 实现),您将需要对哪些列唯一定义一行进行前期分析——可能简单,也可能复杂,具体取决于架构的复杂性;
- 如果您无法添加版本或时间戳列,您将失去 Hibernate 进行乐观锁定的能力,并且最终不得不在更新之前进行查询。
(Added in response to first comment)If you're lucky enough to re-design your database, two very important considerations if you're going to be using an ORM:
- Add a version number column to all relevant tables to support optimistic locking.
- During your data analysis, decide on non-nullable "alternate key" column(s) that developers should use for
hashCode()
&equals()
. Don't use PK columns in those methods.
(针对第一条评论添加)如果您有幸重新设计了数据库,那么如果您打算使用 ORM,则有两个非常重要的注意事项:
- 向所有相关表添加版本号列以支持乐观锁定。
- 在您的数据分析过程中,确定开发人员应用于& 的不可为空的“备用键”列。不要在这些方法中使用 PK 列。
hashCode()
equals()
回答by Joachim Sauer
I'd suggest going with JPA and depending (heavily!) on the duration/scope of your project you might as well look into JPA2, for it provides some of the missing features of JPA (a very nice Query API for example).
我建议使用 JPA 并根据(严重!)项目的持续时间/范围,您不妨研究一下 JPA2,因为它提供了 JPA 的一些缺失功能(例如,一个非常好的查询 API)。
回答by Mauli
If you are indeed have a greenfield project, you may use hibernate, but be aware that the learning curve is quite steep.
如果您确实有一个未开发的项目,则可以使用 hibernate,但要注意学习曲线非常陡峭。
If you have a existing database you are much better of with iBatis, because after one day you are productive and after two more days you can know all about it.
如果您有一个现有的数据库,那么使用 iBatis 会好得多,因为一天后您的工作效率很高,两天后您就可以了解它的全部内容。
One thing you have to consider is, that the hibernate criteria api is excellent for creating custom queries, which depending on your application, may be a good argument for it.
您必须考虑的一件事是,hibernate 标准 api 非常适合创建自定义查询,这取决于您的应用程序,可能是一个很好的论据。
回答by Rob Bygrave
To add another option to the list... have a look at:
要将另一个选项添加到列表中...看看:
Ebean ORM (http://ebean-orm.github.io).
Ebean ORM ( http://ebean-orm.github.io)。
It's main claim would be a simpler more intuitive programming model than JPA or Hibernate. Specifically, it doesn't have a Hibernate Session or JPA EntityManager, no detached/attached objects (no merge, persist, flush), lazy loading just works.
它的主要主张是比 JPA 或 Hibernate 更简单、更直观的编程模型。具体来说,它没有 Hibernate Session 或 JPA EntityManager,没有分离/附加的对象(没有合并、持久化、刷新),延迟加载才有效。
... aka much simpler to use and understand.
...又名更易于使用和理解。
You can also use your own SQL with Ebean (for queries, updates, stored procedures) and IMO it matches Ibatis in ease of use wrt using your own SQL.
您还可以将您自己的 SQL 与 Ebean(用于查询、更新、存储过程)和 IMO 一起使用,它在使用您自己的 SQL 时与 Ibatis 相匹配,易于使用。
If you are looking to use the ORM in Java SE then I'd suggest you check it out.
如果您希望在 Java SE 中使用 ORM,那么我建议您检查一下。
- LGPL Licence
- Use JPA annotations for mapping (@Entity, @OneToMany etc)
- Session-less API (no merge, persist, flush ... save() and delete() instead)
- "Partial Object" support
- Large Query support (per object graph persistence context)
- Background queries
- Good support for batch processing
- Automatic Query tuning (via "Autofetch")
- LGPL 许可证
- 使用 JPA 注释进行映射(@Entity、@OneToMany 等)
- 无会话 API(没有合并、持久化、刷新 ... save() 和 delete() 代替)
- “部分对象”支持
- 大查询支持(每个对象图持久化上下文)
- 后台查询
- 良好的批处理支持
- 自动查询调优(通过“Autofetch”)
Cheers, Rob.
干杯,罗伯。
回答by JavaGuy
Be aware that using JPA/Hibernate (and probably most other ORM solutions) in non-trivial multi-threaded applications can quickly become a real PITA because database sessions need to be confined to exactly one thread (Session objects are not thread-safe). Add lazy loading and the fact that persistent entities can belong to at most one active session...and you're in for a hell of a ride...
请注意,在非平凡的多线程应用程序中使用 JPA/Hibernate(可能还有大多数其他 ORM 解决方案)可以很快成为真正的 PITA,因为数据库会话需要仅限于一个线程(会话对象不是线程安全的)。添加延迟加载以及持久化实体最多可以属于一个活动会话的事实......你会遇到麻烦......
You might want to have a look at Session management using Hibernate in a *multi-threaded* Swing application(or just search for 'hibernate multi-threaded').
您可能想看看在*多线程* Swing 应用程序中使用Hibernate 的会话管理(或者只是搜索“hibernate multi-threaded”)。
My rule of thumb (YMMV): If the application does not lend itself to some kind of request/response cycle (like a webservice for example) , you may probably be better off using something else.
我的经验法则 (YMMV):如果应用程序不适合某种请求/响应周期(例如 Web 服务),那么使用其他东西可能会更好。
Of course, another solution would be to design the application in a way that circumvents the mentioned framework limitations. Changing an application's design so I can get framework XYZ to work leaves a bad aftertaste though.
当然,另一种解决方案是以绕过上述框架限制的方式设计应用程序。更改应用程序的设计以便我可以让框架 XYZ 工作,但会留下不好的回味。
Anyway, just my $0.02
不管怎样,只要我的 0.02 美元