您更喜欢Java ORM,为什么?

252 java orm

这是一个非常开放的问题.我将开始一个新项目,我正在寻找与数据库访问集成的不同ORM.

你有什么收藏吗?你有没有建议保持清醒?

Dav*_*haw 231

我已经停止使用ORM了.

原因不是这个概念有任何重大缺陷.Hibernate运行良好.相反,我发现查询的开销很低,我可以将大量复杂的逻辑放入大型SQL查询中,并将大量处理转移到数据库中.

所以考虑使用JDBC包.

  • ORM一遍又一遍地说:快速的初始开发,以及在跟踪ORM相关错误和低效率时项目中的资源大量消耗.我也讨厌这样一个事实:它似乎让开发人员认为他们永远不必编写特定的优化查询. (79认同)
  • 为什么不同时使用,取决于查询/事务的复杂性?它们不是互相排斥的. (55认同)
  • 我同意.我已经使用ORM超过3年了,我不知道浪费了多少时间(仍然是)来解决与持久性相关的问题.我们无法控制"幕后"发生的事情,配置太多而无法有效管理,并且有些行为可能会让人感到疯狂.另一方面,我支持主要数据库,永远不必担心他们的差异. (29认同)
  • 嘿,这对大型现实生活项目来说都是如此吗? (7认同)
  • @WillSheppard是的Will.我使用Django ORM非常多,而且效果很好.我认为差异可能在于python(和perl)的动态特性.在Java中使用ORM是一件痛苦的事.但在动态语言中,它可以真正表达.有一些伟大的项目可以在Python中嵌入像DSL这样的ORM操作并且很棒. (6认同)
  • 所以你用事务,sql查询,对象映射,变更跟踪,延迟加载,迁移,关系和连接编写了自己的存储库?凉.你写了一个自定义ORM. (5认同)
  • 如何将表行映射到Java对象?您是否使用setter为每个对象设置每个值?始终从用户创建select*; 然后手动将每个用户属性映射到Java对象? (3认同)
  • 不知道,我正在使用最新版本的Hibernate并且没有必要与它斗争,而且我也可以选择在HQL中编写查询,所以它给了我两个世界中最好的东西,就我而言我担心.我来自于在JDBC中编写自己的简单包装器多年. (2认同)

sim*_*mon 95

没有,因为拥有一个ORM需要太多的控制而且收益很小.当您必须调试因使用ORM而导致的异常时,节省的时间很容易被消除.此外,ORM不鼓励开发人员学习SQL以及关系数据库如何工作并使用它来获益.

  • 这取决于.当然,如果您只使用一种特定类型的数据库,那么不使用ORM就可以轻松逃脱.但是,当您需要支持其他类型的数据库时,它很快就会变得不易管理. (15认同)
  • 您的论点可以针对任何库的使用提供.ORM的最大收获是诸如工作单元,对象映射,变更跟踪,延迟加载,迁移和关系之类的东西.能够编写user.profile.givenName并不关心用于存储数据的结构是一件很棒的事情. (6认同)
  • 我同意这个说法.编写持久性代码会占用总开发时间多少?我认为不到10-15% (4认同)
  • "当你必须调试因使用ORM而导致的异常时,所节省的时间很容易被吹走"当技术曲线在采用技术选择时是一个不错的因素时,这种情况并非如此. (3认同)

小智 86

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

  • SQL是件好事.在SQL中可以很好地表达很多东西.不需要完全抽象SQL.
  • 关系数据模型是一件好事.它已被证明是过去40年来最好的数据模型.不需要XML数据库或真正面向对象的数据模型.相反,您的公司运行Oracle,MySQL,MSSQL,DB2或任何其他RDBMS的多个实例.
  • SQL具有结构和语法.它不应该使用JDBC中的"低级"字符串连接来表达 - 或者在HQL中使用"高级"字符串连接 - 两者都容易出现语法错误.
  • 在处理主要查询时,变量绑定往往非常复杂.这是应该抽象的东西.
  • 编写处理数据库数据的Java代码时,POJO非常棒.
  • POJO是手动编写和维护的痛苦.代码生成是可行的方法.您将拥有编译安全查询,包括datatype-safety.
  • 数据库是第一位的.虽然数据库顶部的应用程序可能会随着时间的推移而发生变化,但数据库本身可能会持续更长时间.
  • 是的,您的旧数据库中确实存在过程和用户​​定义的类型(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);
Run Code Online (Sandbox Code Playgroud)

以及它如何在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))))));
Run Code Online (Sandbox Code Playgroud)

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

Abd*_*aly 57

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

它甚至被移植到.NET(NHibernate),所以你也可以在那里使用它.

  • 我也投了Hib,但是有一个重要的补充:我们应该只使用JPA API*,即使JPA实际上是由Hib提供的. (4认同)

Boz*_*zho 51

Hibernate,因为它:

  • 是稳定的 - 这么多年来,它没有任何重大问题
  • 规定了ORM领域的标准
  • 实现标准(JPA),除了指示它.
  • 在互联网上有大量关于它的信息.有许多教程,常见问题解决方案等
  • 功能强大 - 您可以将非常复杂的对象模型转换为关系模型.
  • 它支持任何主要和中型RDBMS
  • 一旦你学得很好,就很容易使用

关于使用ORM的原因(以及何时)的几点:

  • 您使用系统中的对象(如果您的系统设计得很好).即使使用JDBC,您最终也会创建一些转换层,以便将数据传输到对象.但我的抱怨是,hibernate在翻译方面比任何定制解决方案都要好.
  • 它不会剥夺你的控制权.您可以在非常小的细节中控制事物,如果API没有某些远程功能 - 执行本机查询就可以了.
  • 任何中型或大型系统都无法承受一吨查询(无论是在一个地方还是分散在一起),如果它的目的是可维护的话
  • 如果表现不重要.Hibernate增加了性能开销,在某些情况下不能忽略.


adr*_*rau 25

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

  • Ibatis用于复杂的读取,而hibernate用于创建,更新删除和简单读取是完美的选择. (10认同)

小智 18

在编写中型JavaSE应用程序时,我对Avaje Ebean有很好的体验.

它使用标准的JPA注释来定义实体,但是公开了一个更简单的API(No EntityManager或任何附加/分离的实体crap).它还允许您在必要时轻松使用SQL查询或事件纯JDBC调用.

它还有一个非常好的流畅和类型安全的API查询.你可以写下这样的东西:

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

  • 我一定有点奇怪...从性别='M'和年龄<18的人中选择firstName对我来说看起来好多了:-) (4认同)
  • 这是我在java中看到的更好的一个.使用单身人士的决定令人耳目一新,并且与其他人相比具有巨大的实用优势. (4认同)

Dav*_*itt 11

SimpleORM,因为它是直接的,没有魔力.它定义了Java代码中的所有元数据结构,并且非常灵活.

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

但与Hibernate不同,SimpleORM使用非常简单的对象结构和体系结构,无需复杂的解析,字节码处理等.IllORM小而透明,包装在两个仅79K和52K的罐子中,只有一个小而且可选依赖(Slf4j).(Hibernate超过2400K加上大约2000K的依赖Jars.)这使SimpleORM易于理解,从而大大降低了技术风险.


Tom*_*and 10

Eclipse Link,原因很多,但值得注意的是,我觉得它比其他主流解决方案(至少不那么臃肿)更少膨胀.

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


Mir*_*emm 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 的理由。

  • 如果您像我们许多人一样在持久存储之上构建应用程序,无论是 RDBMS 还是某种 NoSQL 风格,该存储都将拥有自己的高效访问方式。试图从中抽象出来太多只是过度设计。过于热衷于“真正的 OOD”会导致 Java 臭名昭著的宇航员架构。 (13认同)