您更喜欢哪种Java ORM,为什么?[关闭]


262

这是一个很开放的问题。我将开始一个新项目,并研究与数据库访问集成的不同ORM。

你有什么喜欢的吗?您有什么建议要远离吗?



看看微规范-围绕平台数据库访问技术的薄包装-例如sql2o for Java github.com/aaberg/sql2o 或ServiceStack.OrmLite for .NET github.com/ServiceStack/ServiceStack.OrmLite
tomaszkubacki

3
使用ORM超过5年后,我个人选择的是Spring JDBC over ORM,第二好的选择是iBatis(MyBatis),由于学习曲线,控制和性能问题较少,我不喜欢休眠。

这是(可以关闭的)轻型jdbc包装器的列表,这些包装器可以替代成熟的
orms

Answers:


237

我已经停止使用ORM。

原因不是概念上的任何重大缺陷。休眠状态很好。相反,我发现查询的开销很低,并且我可以将很多复杂的逻辑放入大型SQL查询中,并将很多处理转移到数据库中。

因此,请考虑仅使用JDBC包。


81
对于ORM来说,这是一遍又一遍的故事:不错的快速初始开发,并且在跟踪与ORM相关的错误和低效率时,大量资源消耗在项目上。我也讨厌这样的事实,即它似乎使开发人员不必再编写特定的优化查询。
Eelco 2010年

7
嘿,对于大型现实生活项目来说,这一切都是真的吗?
santiagobasulto,2010年

30
我同意。我已经使用ORM超过3年了,我不能说花了多少时间(仍然是)来解决与持久性相关的问题。我们根本无法控制“幕后”发生的事情,配置太多,无法有效管理,并且有些行为可能使人发疯。另一方面,我对主要数据库有支持,而不必担心它们之间的差异。
marcolopes 2011年

58
为什么不同时使用这两种方法,具体取决于查询/事务的复杂性?并不是说它们是互斥的。
两栖游戏,2012年

6
@WillSheppard是的。我经常使用Django ORM,效果很好。我认为差异可能在于python(和perl)的动态特性。在Java中使用ORM是一种痛苦。但是在动态语言中,它确实可以表达。有一些很棒的项目可以将ORM操作(例如DSL)嵌入Python中,并且很棒。
santiagobasulto

97

不会,因为拥有ORM会使您失去太多控制权并带来小好处。当您必须调试因使用ORM而导致的异常时,节省的时间很容易被浪费掉。此外,ORM阻碍了开发人员学习SQL以及关系数据库的工作方式,并因此而受益。


4
我同意这一说法。编写持久性代码会消耗总开发时间中的多少?我认为不到10-15%
adrian.tarau

16
这取决于。当然,如果您仅使用一种特定类型的数据库,那么不使用ORM就很容易逃脱。但是,当您需要支持其他类型的数据库时,它很快就变得难以管理。
杰森·贝克

3
“当您必须调试因使用ORM而导致的异常时,节省的时间很容易被浪费掉。”当技能曲线是选择技术时的体面因素时,情况并非如此。
elsadek 2014年

7
可以反对使用任何库来提出您的论点。ORM的最大收获是诸如工作单元,对象映射,变更跟踪,延迟加载,迁移和关系之类的东西。能够编写user.profile.givenName而不用关心使用什么结构来存储数据是一件很了不起的事情。
亚历克斯(Alex)

1
它可用于任何库,但程度不同。通常,我是使用库的大力提倡者-为什么要重新发明轮子?但是,在这种情况下,我觉得Hibernate在大多数情况下使用的都是太重的重量,而更轻量的ORM更可取。我的经验是基于几年来与Hibernate一起开发并全面了解其来龙去脉的经验。
simon 2014年

92

许多ORM很棒,您需要知道为什么要在JDBC之上添加抽象。我可以向您推荐http://www.jooq.org(免责声明:我是jOOQ的创建者,所以这个答案有偏见)。jOOQ包含以下范例:

  • SQL是一件好事。用SQL可以很好地表达很多事情。无需完全抽象SQL。
  • 关系数据模型是一件好事。它被证明是过去40年来最好的数据模型。不需要XML数据库或真正的面向对象的数据模型。而是,您的公司运行Oracle,MySQL,MSSQL,DB2或任何其他RDBMS的多个实例。
  • SQL具有结构和语法。不应在JDBC中使用“低级”字符串连接来表示-或在HQL中使用“高级别”字符串连接来表示这两者都容易出现语法错误。
  • 在处理主要查询时,变量绑定往往非常复杂。那是应该抽象的东西。
  • 当编写用于处理数据库数据的Java代码时,POJO非常有用。
  • POJO很难手动编写和维护。代码生成是必经之路。您将拥有包括数据类型安全性在内的编译安全查询。
  • 数据库是第一位的。虽然数据库顶部的应用程序可能会随着时间而变化,但数据库本身的使用寿命可能会更长。
  • 是的,您的旧数据库中确实有存储过程和用户​​定义类型(UDT)。您的数据库工具应支持这一点。

还有许多其他好的ORM。特别是Hibernate或iBATIS拥有一个强大的社区。但是,如果您正在寻找一种直观,简单的方法,我会说尝试一下jOOQ。你会爱上它!:-)

查看以下示例SQL:

  // Select authors with books that are sold out
  SELECT * 
    FROM T_AUTHOR a
   WHERE EXISTS (SELECT 1
                   FROM T_BOOK
                  WHERE T_BOOK.STATUS = 'SOLD OUT'
                    AND T_BOOK.AUTHOR_ID = a.ID);

以及如何在jOOQ中表达:

  // Alias the author table
  TAuthor a = T_AUTHOR.as("a");

  // Use the aliased table in the select statement
  create.selectFrom(a)
        .whereExists(create.selectOne()
                           .from(T_BOOK)
                           .where(T_BOOK.STATUS.equal(TBookStatus.SOLD_OUT)
                           .and(T_BOOK.AUTHOR_ID.equal(a.ID))))));

1
ORM工具与您设法正确使用它们一样好。在某些项目中,ORM工具的工作方式很吸引人,而在其他项目中,它们根本不合适。最后,开发团队有责任选择适合其项目需求的工具。ORM工具很复杂。不幸的是,所有开发人员中只有一部分会花时间了解他们的工作方式。其余的只会责怪该工具,并说这是不好的。问题是:最受支持的答案是否提供最佳建议?>因此,请考虑仅使用JDBC软件包。我们真的要使用纯JDBC吗?
Vlad Mihalcea '16年

我尽量不要让“数据库优先”。应用程序包含客户要求的功能的业务规则,而他们几乎从不要求创建数据库。这是在实施过程中确定的技术细节。
Kwebble

58

Hibernate,因为它基本上是Java中的事实上的标准,并且是创建JPA的推动力之一。它在Spring中得到了很好的支持,几乎每个Java框架都支持它。最后,GORM是一个非常酷的包装器,它可以进行动态查找器等等使用Groovy的过程。

它甚至已移植到.NET(NHibernate),因此您也可以在其中使用它。


4
我也投票给Hib,但还有一个重要的补充:即使Hib实际上提供了JPA实现,我们也应该使用JPA API 。
弗拉基米尔·朱热夫(Fladimir Dyuzhev)2009年

52

休眠,因为它:

  • 是稳定的-已经存在很多年了,它没有任何重大问题
  • 决定ORM领域的标准
  • 除了规定标准外,还实施标准(JPA)。
  • 在Internet上有大量有关它的信息。有很多教程,常见问题解决方案等
  • 功能强大-您可以将非常复杂的对象模型转换为关系模型。
  • 它支持任何主要和中等的RDBMS
  • 一旦学好就容易使用

关于为什么(以及何时)使用ORM的几点:

  • 您可以使用系统中的对象(如果您的系统设计合理)。即使使用JDBC,您最终也会创建一些转换层,以便将数据传输到对象。但是我敢打赌,休眠模式比任何定制解决方案都更适合翻译。
  • 它不会剥夺您的控制权。您可以控制非常小的细节,并且如果API没有某些远程功能-执行本机查询就可以了。
  • 如果中型或大型系统旨在保持可维护性,那么它将无法承受一吨的查询(无论是在一个地方还是分散在多个地方)
  • 如果性能不是很关键。Hibernate增加了性能开销,在某些情况下这是不容忽视的。

当我比较Hibernate和JPA时,我会选择Hibernate,如果比较JPA和JDO,我会选择JDO!我非常喜欢JDO,但是我喜欢Hibernate的两个功能(JDO中不可用),一个是@Filters,另一个是您可以将版本字段(用于乐观锁定)映射到普通字段中,这在JDO中是不可能的。
2012年

27

我建议使用MyBatis。它是JDBC之上的一个薄层,它很容易将对象映射到表并仍然使用普通SQL,一切都在您的控制之下。


10
Ibatis适用于复杂读取,而休眠则用于创建,更新删除和简单读取是最佳选择。
darpet

19

在编写中等大小的JavaSE应用程序时,我在Avaje Ebean方面拥有非常不错的经验。

它使用标准的JPA批注定义实体,但是公开了更简单的API(没有EntityManager或任何附着/分离的实体废话)。它还使您可以在必要时轻松使用SQL查询或事件纯JDBC调用。

它还具有一个非常好的流体查询和类型安全的API。您可以编写如下内容:

List<Person> boys = Ebean.find(Person.class)
                                  .where()
                                       .eq("gender", "M")
                                       .le("age", 18)
                                  .orderBy("firstName")
                                  .findList();

6
我一定有点怪异...从Person那里选择性别='M'并且firstName年龄小于18的人对我来说看起来好多了:-)
Eelco 2010年

4
这是我在Java中看到的更好的规范之一。使用单例的决定令人耳目一新,并赋予了它比其他单例更大的实际优势。
opsb 2010年

我想你的意思是流利而不流畅。
Montdidier

@opsb从技术上讲,我认为这是一个单州,而不是单身人士。
Montdidier

如何开始使用Avaje Ebean ORM?有视频教程吗?
阿维纳什(Avinash)

11

SimpleORM,因为它简单明了且没有魔法。它用Java代码定义了所有元数据结构,并且非常灵活。

SimpleORM通过将关系数据库中的数据映射到内存中的Java对象,提供了与Hibernate类似的功能。可以根据Java对象来指定查询,将对象标识与数据库键对齐,维护对象之间的关系,并使用乐观锁将修改后的对象自动刷新到数据库。

但是与Hibernate不同,SimpleORM使用非常简单的对象结构和体系结构,避免了复杂的解析,字节码处理等需求。SimpleORM小而透明,包装在大小分别为79K和52K的两个jar中,只有一个小且可选依赖关系(Slf4j)。(Hibernate超过2400K,再加上大约2000K的从属Jar。)这使SimpleORM易于理解,从而大大降低了技术风险。


尚未使用它,但ActiveObjects在其网站上将自己描述为一种Hibernate-lite,因此可能存在一些相似之处。
阿卜杜拉·吉巴利

10

Eclipse Link的原因很多,但值得注意的是,我感觉它的膨胀程度比其他主流解决方案要小(至少脸部膨胀程度要小)。

哦,Eclipse Link已被选为JPA 2.0的参考实现。


5

尽管我也分享了有关用Java替换自由格式SQL查询的担忧,但我确实确实认为批评ORM的人这样做的原因是应用程序设计普遍较差。

真正的OOD由类和关系驱动,ORM为您提供不同关系类型和对象的一致映射。如果您使用ORM工具并最终以ORM框架支持的任何查询语言(包括但不限于Java表达式树,查询方法,OQL等)对查询表达式进行编码,那么您肯定做错了,即您的类模型最有可能无法以应有的方式满足您的要求。干净的应用程序设计实际上并不需要在应用程序级别上进行查询。我一直在重构许多人们开始使用ORM框架的项目,就像他们在代码中嵌入SQL字符串常量一样,最后,每个人都为一旦匹配就使整个应用程序变得如此简单和可维护感到惊讶。使用模型建立您的类模型。当然,对于搜索功能等来说,您需要一种查询语言,但是即使如此,查询仍然受到很大的限制,以至于创建甚至复杂的VIEW并将其映射到只读持久类都比构建表达式要维护和查看的好得多。应用程序代码中的某些查询语言。VIEW方法还利用了数据库功能,并且通过实现,在性能方面要比Java源代码中的任何手写SQL更好。因此,我认为非平凡应用程序不使用ORM的任何理由。但是即使这样,查询仍然受到很大的限制,以至于创建甚至是复杂的VIEW并将其映射到只读持久类都比在应用程序代码中以某种查询语言构建表达式要好得多。VIEW方法还利用了数据库功能,并且通过实现,在性能方面要比Java源代码中的任何手写SQL更好。因此,我认为非平凡应用程序不使用ORM的任何理由。但是即使这样,查询仍然受到很大的限制,以至于创建甚至是复杂的VIEW并将其映射到只读持久类都比在应用程序代码中以某种查询语言构建表达式要好得多。VIEW方法还利用了数据库功能,并且通过实现,在性能方面要比Java源代码中的任何手写SQL更好。因此,我认为非平凡应用程序不使用ORM的任何理由。


11
如果像我们很多人一样,在持久性存储之上构建应用程序,无论是RDBMS还是某种NoSQL风格,该存储都将拥有自己的有效访问方式。试图从太多的东西中抽象出来只是过度工程。对“真正的OOD”过于热心会导致Java臭名昭著的宇航员体系结构。
Eelco
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.