为啥人们继续使用 xml 映射文件而不是注释? [关闭]

Posted

技术标签:

【中文标题】为啥人们继续使用 xml 映射文件而不是注释? [关闭]【英文标题】:Why are people continuing to use xml mapping files instead of annotations? [closed]为什么人们继续使用 xml 映射文件而不是注释? [关闭] 【发布时间】:2010-12-24 04:13:24 【问题描述】:

我观察到一个奇怪的事实(基于 hibernate 标记中的问题),人们仍在积极使用 xml 文件而不是注释来指定他们的 ORM (Hibernate/JPA) 映射。

在某些情况下,这是必要的:

您正在使用提供的类,并且想要映射它们。 您正在编写一个 API,其域类可以在没有 JPA 提供程序的情况下使用,因此您不想强制依赖 JPA/Hibernate。

但我认为这些并不常见。

我的假设是:

人们习惯于使用 xml 文件,感觉不舒服/不想费心学习使用注释方法。 Java pre-1.5 被强加在项目上,没有什么可做的 人们不知道注释是 xml 映射的全功能替代品。 支持旧系统,因此更改方法存在风险 人们担心将注释(元信息)与他们的类混合是错误的。

还有其他可能的解释吗?

【问题讨论】:

我想你已经把它们都搞定了。但反问:你为什么在乎? 我想这只是许多企业在 Java 1.4 上运行遗留系统,需要与否则会使用注释的新代码兼容。甚至这种可能性也可能迫使项目继续使用笨重的 XML 文件。过去使用过 JPOX/JDO,我不明白为什么有正常思维的人如果有其他选择会想要继续使用映射文件。 通过“任何替代”,我包括将自己从悬崖上跳下来作为使用 JPOX/JDO 的可行替代方案。 @JeeBee,JPOX 已经将近 2 年没有开发了。现在它被称为 DataNucleus,它支持比任何其他持久性解决方案更灵活的元数据输入机制。 --Andy (DataNucleus 不是大多数用户的想法。 XML 从第一天开始就可用。当 Java5 投入生产时,JDO 有注释……实际上来自 JPOX 1.1。显然,如果你当时有一些问题,那么你可以提出这个问题。与以往一样,对事情保持建设性总是更好,因为这样可以完成某些事情。祝你有美好的一天 【参考方案1】:

域层和持久层被一些人认为是独立的关注点。使用纯 XML 方法使两层尽可能松散耦合;使用注释可以更紧密地耦合两层,因为您在域代码中嵌入了与持久性相关的代码。

【讨论】:

这是一个公平的观点,尽管我不认为此时耦合是有害的。除了运行时依赖之外,对象可以像从持久性元数据中解耦一样使用。还有持久化元数据,好吧,没有领域对象就不能使用它。 disagree 和 @kem。注释旨在分离我们在域和持久性之间讨论的那些关注点。并且注释比单独的 XML 文件更好,正如#Bozho 提到的那样,我们需要定位并打开这两个文件,因此注释做得更好。更多使用 XML 的真正原因(即使是在 2014 年的今天)是开发人员社区需要一些时间才能加入。 Hibernate 等可能会继续支持 XML 以实现向后兼容性。 我同意@kem 100%。我不希望我的领域层附近的任何持久性信息,如果没有其他原因,只是在尝试处理领域逻辑时它给开发人员带来的认知负担。关注点分离不限于一个类 - 关注点分离在文件、目录和软件层中起作用。【参考方案2】: 缺乏对所映射内容的概述。您需要深入挖掘源代码。

【讨论】:

【参考方案3】:

人们不知道注释是 xml的全功能替代品 映射。

啊,但他们不是。我脑海中浮现的三个案例(可能还有更多)你不能(很好)使用注释:

    Use formula as part of association key(诚然,相当深奥)。 Join-via-subselect - @Loader 不是一个合适的替代品。不是常见但非常有用。 Envers 提供了一种可行的替代方法。 模式生成的列顺序丢失。这个绝对是杀手锏。我明白为什么要这样做,但它仍然让我烦恼不已。

不过,不要误会我的意思 - 注释很棒;当它们与 Validator 结合使用时(尽管如此,上面的#3 再次扼杀了这一点)。它们还提供了 XML 映射不具备的某些功能。

【讨论】:

失去列顺序真的是个大问题吗?这肯定不是很好,但我目前正在使用具有 30 多列的生成表,这没什么大不了的。 如果您使用 Hibernate 来生成您的架构,这将是一个问题 - 直接或通过 liquibase。我所说的“问题”并不是指“它不起作用”——但是通过外部工具使用(甚至查看)生成的数据库非常不方便。除非您按字母顺序命名您的属性:-) 诸如主键/外键之类的东西将在您的表中随机出现(如“与源代码中的不同”)位置。也许只是我,但这会杀了我 - 在一定程度上我不得不修补注释绑定器以使用一些 javassist 黑魔法来保留属性顺序:-) 呵呵。是的,我正在使用直接模式生成,我认为这是一个小小的不便。顺便说一句,你有没有在某个地方提交过补丁? 很遗憾,出于法律原因,我不能。然而,根据过去的经验,它可能无论如何都不会被接受 - Hibernate 团队非常嗯......选择性:-) 除了直接错误之外的任何东西。此外,javassist 确实是黑魔法;我已经部署并在 3 个独立的平台上工作,但我不知道它是否会在其他平台上始终如一地工作。如果您对此感兴趣,请告诉我——我无法提供实际代码,但我会给出一些建议;一旦你知道在哪里看,写起来并不难。 在 Oracle 数据库中,最好在表的末尾包含空列。最后的所有空列都不占用空间(注意,不是“非常小的空间”,而是根本没有空间)。【参考方案4】:

在需要环境或系统特定配置的情况下,使用 XML 补充注释。

【讨论】:

在处理依赖注入配置时更是如此。当您有一个具有大量配置的大型应用程序时,使用全部/纯注释方法很难全面了解您的应用程序是如何捆绑在一起的。在这种情况下,XML 配置是一个非常好的补充,您可以在其中进行某种程度的集中式配置,从而全面了解所有拼图如何组合在一起。 虽然你是对的,但从其他方面来看,整个谜题应该是显而易见的,例如包装、命名等 :)【参考方案5】:

注释中很好地承载了一些信息,例如实体之间关系的基数。这些注释提供了有关模型本身的更多详细信息,而不是模型与其他事物的关系。

但是,绑定,无论是持久存储还是 XML 或其他任何东西,都是模型外在的。它们根据使用模型的上下文而变化。在模型中包含它们与在 html 中使用内联样式定义一样糟糕。我使用外部绑定(通常——但不一定——XML)文档的原因与我引用外部 CSS 的原因相同。

【讨论】:

虽然我同意这是最有效的观点,但我个人认为这种分离不是那么必要。即使存在需要更改注释的上下文(例如,RDBMS 的怪异之处),也可以用一个小的映射文件覆盖特定的有问题的地方。 (使用外部 CSS 的一点是重用定义,这里我们没有这样的选择。) 我使用 CSS 的最大动机是分离 角色。在开发中,存在一些奇怪的循环,其中绑定特定构造的难度实际上会影响模型设计,但开发人员很快就会内化一些经验法则,让他们创建模型而不必过多担心绑定。之后,将建模和绑定的工作分摊到人甚至团队之间是合理的。还有一点值得一提:在 XML 绑定的情况下,一个模型很可能会绑定到多个模式。外部绑定可以实现这一点。【参考方案6】:

我最初发现注释语法很奇怪。它看起来像线路噪音,并与我通常放置 cmets 的位置混合在一起。不过,它比处理 XML 文件要好得多,因为所有更改都在一个地方,即模型文件。也许注释的一个限制是可能与其他注释发生冲突,但我还没有看到。

我认为它没有被更多使用的真正原因是它并没有真正被视为默认值。您必须使用额外的 jar 文件。它应该是核心的一部分,而 XML 方法应该是可选的。

【讨论】:

【参考方案7】:

我已切换到注释,但有时我会错过 XML 映射,主要是因为文档更加全面,包含许多场景的示例。对于注释,我坚持使用非常基本的映射(如果您控制数据和对象模型,那就太好了),但是我在 XML 中做了一些非常复杂的事情,我不知道是否可以在注释中复制。

【讨论】:

【参考方案8】:

因此,如果您想将您的课程部署到多个数据存储区。您想将列定义注释到其中吗?不同的数据存储有不同的约定等,在这种情况下使用 XML 是唯一合理的地方,能够有一个用于 mysql,一个用于 Derby,一个用于 Oracle 或其他。如果您愿意,您仍然可以放入基本的持久性/关系注释,但在这种情况下,特定于模式的内容将进入 XML。

--安迪(DataNucleus)

【讨论】:

配置命名约定的更好地方是 NamingStrategy。 谁在谈论命名约定?列长度​​、列类型等也是跨 RDBMS 类型的变量。很多东西。 JPA 没有这样的命名策略。显然,如果您已经决定只使用注释,那么只需使用它们,但不要说您没有被警告。 而且我没有说使用 xml 是错误的。 (并且反对票不是我的;))。 Hibernate 有 NamingStrategy。还有什么其他约定?一般来说,ORM 映射应该与数据库无关。 如果一个 RDBMS 支持 BLOB 而另一个不支持,那么?在某些情况下,您需要以一种方式和另一种不同的方式存储布尔值。它们并不都支持相同的 JDBC 类型。显然,这取决于数据存储可移植性是否是您的应用程序需要在许多环境中部署的问题;对于许多应用程序而言并非如此。【参考方案9】:

我有一个新的:http://www.summerofnhibernate.com/

非常不错的截屏系列,尚未涵盖注释。我用它编写了一些应用程序来学习基础知识,不是为了我的工作,而是出于好奇,但还没有迁移到注释。建议的系列仍然与 SO 相关。如果我有更多空闲时间,我仍然会迁移到注释,但目前我可能是提出问题的人之一。

【讨论】:

【参考方案10】:

我在一个项目中工作,其中数据库会非常频繁地更改,并且每次发生时我们都必须重新生成 java 文件和配置文件。实际上我们并没有使用hibernate工具生成的所有关系和配置。所以基本上我们使用该工具,然后修改/调整它们。

因此,当您想要修改/调整默认配置时,与通过注释进行相比,在 XML 文件中进行操作更容易。

【讨论】:

我认为数据库更改应该跟随模型更改,而不是先于它。【参考方案11】:

我觉得如果我们不使用Annotations它会使代码更具可读性。如果配置信息经常更改,使用Annotations确实有帮助,但是以web.xml为例,该信息更改了多少次,那么为什么要为 Servlet 使用注解。

【讨论】:

如果 servlet API 有注释(它们将出现在 3.0 中),我会问同样的问题。在我看来,阅读带注释的类比在类和映射之间进行并行更容易。 我认为这主要是一个选择问题。对我来说,阅读 10 行代码比阅读 10 行代码 + 10 或 20 多行配置信息更好。【参考方案12】:

我们继续使用 XML,因为通常对于已部署的站点,获得批准安装的补丁(二进制代码)需要您可能没有的时间。对 ASCII 文件(例如 xml 文件)的更新被视为配置更改,而不是补丁...

t

【讨论】:

以上是关于为啥人们继续使用 xml 映射文件而不是注释? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥人们会缩小资产而不是 HTML?

为啥我的 Perl 映射不返回任何内容?

为啥在这个 Hibernate 映射中使用 @ManyToOne 而不是 @OneToOne?

PHP读取文件注释而不是文件内容 - 忘记了

Hibernate 注释用法

为啥 Java 8 中的哈希映射使用二叉树而不是链表? [关闭]