如何将不同的 Java-Bean 结构相互映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/374302/
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
How to map different Java-Bean structures onto one another
提问by Hans-Peter St?rr
In our project we have to map one nested structures of beans onto another. (These are actually JAXB mapped Java-Representations of XML documents that, say, represent an incoming order document.) This has to be mapped onto the quite different order document structure of another system.
在我们的项目中,我们必须将 bean 的一个嵌套结构映射到另一个。(这些实际上是 XML 文档的 JAXB 映射 Java 表示,比如说,表示传入的订单文档。)这必须映射到另一个系统的完全不同的订单文档结构上。
What are the options to do this? I would prefer something that fulfills the following requirements:
有哪些选项可以做到这一点?我更喜欢满足以下要求的东西:
- The mapping should alert me when the mapping of one field was not defined
- The mapping should have some defaults, like mapping fields of equal names onto one another and providing standard mappings for, say, int to String and vice versa.
- The mapping should be bidirectional.
- One should be able to use code completion when defining the mapping.
- 当一个字段的映射没有定义时,映射应该提醒我
- 映射应该有一些默认值,比如将同名字段相互映射,并提供标准映射,比如 int 到 String,反之亦然。
- 映射应该是双向的。
- 定义映射时应该能够使用代码完成。
A promising framework for this is Dozer, but it does not fulfill 1 and 4. Same with JBeanMapper. Just programming it in Java does 4 but not the other requirements; using XSLT fulfills perhaps 2 but nothing else. Do you have better ideas?
一个很有前途的框架是Dozer,但它不满足 1 和 4。与JBeanMapper相同。仅用 Java 编程即可满足 4 项要求,但不满足其他要求;使用 XSLT 可能满足 2 但仅此而已。你有更好的想法吗?
回答by Jonathan
ModelMapperis the one library that meets all of your criteria. It offers a mapping API that uses actual code to map properties - so you get code completion. And it offers validation to ensure that all destination properties are mapped. Additionally it offers some things you didn't even know you wanted such as intelligent mapping :)
ModelMapper是一个满足您所有条件的库。它提供了一个映射 API,该 API 使用实际代码来映射属性 - 因此您可以获得代码完成。它提供验证以确保映射所有目标属性。此外,它还提供了一些您甚至不知道自己想要的东西,例如智能地图:)
Check out the ModelMapper homepage for more info:
查看 ModelMapper 主页了解更多信息:
回答by Gunnar
回答by Denis
Have a look at GeDA which uses byte code to create mapping classes during runtime, which makes it extremely fast http://genericdtoassembler.org/. It would cover point 1-3. Regarding point 4 I would imagine it is an IDE thing so I do not think you will find any library that would facilitate that unless it has IDE plugins.
看看 GeDA,它使用字节码在运行时创建映射类,这使得它非常快http://genericdtoassembler.org/。它将涵盖第 1-3 点。关于第 4 点,我认为这是一个 IDE 的东西,所以我认为除非它有 IDE 插件,否则你不会找到任何可以促进这一点的库。
回答by Sai Hegde
Transmorph, EZMorph, Dozer, OTOM are some of them you could look at for Bean to Bean mapping. I have used Dozer in the past and feel that it has grown quite stable over years.
Transmorph、EZMorph、Dozer、OTOM 是其中一些您可以查看 Bean 到 Bean 映射的工具。我过去使用过 Dozer,感觉多年来它变得非常稳定。
回答by JeeBee
When we've had this problem, we've ended up doing field mappings in Java in a utility class. It's a real hassle, especially when you have to map to several different web services and have to write mappings for each of them (some of which are a simple 2D map of named attributes rather than a hierarchy of objects, cries).
当我们遇到这个问题时,我们最终在 Java 中的实用程序类中进行字段映射。这是一个真正的麻烦,尤其是当您必须映射到几个不同的 Web 服务并且必须为每个服务编写映射时(其中一些是命名属性的简单 2D 映射,而不是对象的层次结构,cries)。
However in that way you do have the power to analyse the requirements of the target of the mapping to get the best quality mapping, setting defaults where data isn't set, and so on. You can throw a custom "UndefinedMappingException" in your mapper where you need to. And by not being a fluffy library that uses reflection and/or complex XML mapping configuration files, it's a darn sight faster.
但是,通过这种方式,您确实有能力分析映射目标的要求以获得最佳质量的映射,在未设置数据的情况下设置默认值,等等。您可以在映射器中需要的地方抛出自定义的“UndefinedMappingException”。而且由于不是使用反射和/或复杂的 XML 映射配置文件的蓬松库,因此速度更快。
I.e., this is the post arguing for "write it in Java".
即,这是争论“用 Java 编写”的帖子。
回答by Aaron Digulla
I solved a similar issue with commons-beanutils.
我用commons-beanutils解决了一个类似的问题。
My final goal was a big Java file which would build the data structure and the mapper created that file for me. This way, I could create test data from snapshots made while the program was running.
我的最终目标是一个大的 Java 文件,它将构建数据结构,映射器为我创建该文件。这样,我可以从程序运行时制作的快照创建测试数据。
The mapper allowed to define the keys by which to sort the objects, the field to use to generate object names in the Java file and I used a map with "class:field" as the key. The value was an object implementing a simple "Mapping" interface (one method: toJava(Object instance, String field, Object value)).
映射器允许定义用于对对象进行排序的键、用于在 Java 文件中生成对象名称的字段,我使用了一个以“class:field”作为键的映射。该值是一个实现简单“映射”接口的对象(一种方法:toJava(Object instance, String field, Object value))。
My main problem was to compile 2MB+ Java files :)
我的主要问题是编译 2MB+ Java 文件:)
回答by Hans-Peter St?rr
There is an interesting solution that might help you if you are mapping data structures that have many slightly different variants. For example if you are modelling business order structures for different business cases and product variants, and different variants require different combinations of the same attributes like adresses, account ids, configuration information for the products etc.
如果您要映射具有许多略有不同的变体的数据结构,则有一个有趣的解决方案可能会对您有所帮助。例如,如果您正在为不同的业务案例和产品变体建模业务订单结构,并且不同的变体需要相同属性的不同组合,例如地址、帐户 ID、产品的配置信息等。
Thus, you have many structurally similar beans that contain different subsets of a number of attributes. If you do not want to write code for each individual variant, you could introduce a Java-interface that has all attributes that occur in these beans, and use java.lang.reflect.Proxyto construct proxy instances for the bean you want to map, and which returns null for getters the actual bean does not have / throws an exception if a non existent setter is called on the actual bean. In a manner of speaking, you inject an interface into those beans that has more methods than the bean itself.
因此,您有许多结构相似的 bean,它们包含许多属性的不同子集。如果您不想为每个单独的变体编写代码,您可以引入一个 Java 接口,该接口具有这些 bean 中出现的所有属性,并使用java.lang.reflect.Proxy为您要映射的 bean 构造代理实例, 并且为 getter 返回 null 实际 bean 没有/如果在实际 bean 上调用不存在的 setter,则抛出异常。从某种意义上说,您将一个接口注入到那些比 bean 本身具有更多方法的 bean 中。

