从领域对象生成DTO和映射器

16

我有很多Java领域对象需要转换为DTO。

请不要提反模式,领域对象是它们的历史使然,我不能修改它们(或者只能稍微修改,见下文)。

当然,手工操作已经过时了。我找了一圈,dozer似乎是DTO映射的首选框架。

但是……我真正想要的是:注释我想在DTO中使用的类和字段,然后运行一个工具,生成DTO和映射器。

这听起来太不现实了吗?

这样的工具已经存在了吗?


可能是的,但了解你指的是哪种编程语言可能会有所帮助。Java/.Net? - JasonTrue
是的...抱歉...我问完问题后意识到了。我已经更新了它。 - Nicolas C
Dozer是一个可怕的、缓慢的、黑盒子式的工具,很难调试和维护,存在各种问题,如映射集合、在任何复杂关系中就地更新对象等。定制也很困难... 呃。最好手写映射:快速、可调试、可通过IDE重构。我的两分钱。 - Peter Davis
@NicolasC:你最终找到工具了吗?如果是的话,你用的是哪个?似乎没有一个答案真正回答了生成DTO(“我有很多Java领域对象需要转换为DTO。”)的需求,这正是我现在所需要的。所有答案似乎都假定DTO已经存在。 - AbVog
5个回答

13
考虑查看我的ModelMapper。 与Dozer和其他库不同的是,它通过智能映射对象模型来最小化所需的配置量。在需要配置时,ModelMapper提供了一个重构安全的API,使用实际代码映射属性和值,而不是使用字符串引用或XML。 查看ModelMapper网站获取更多信息: http://modelmapper.org

2
ModelMapper 只生成映射器而不是 DTO 吗? - Alessio

8

您可能会对MapStruct感兴趣,它是JavaBeans映射器的代码生成器。您需要实现源模型(例如您的领域对象)和目标模型(例如DTO),然后MapStruct将为这些模型之间的映射生成类型安全且快速的代码(声明:我是该项目的作者)。


3

这篇帖子有点老了,但如果有人仍在尝试这样做,http://www.dtonator.org/ 是目前我发现的最好的选择。它是我能找到唯一实际创建DTO文件而不被绑定到特定框架(Spring、Seam等)或IDE的工具。


2

1

也许有点晚了,最近我开发了一个注解处理器叫做beanknife,它支持从任何类生成DTO。你需要通过注解进行配置。但是你不需要改变原始类。这个库支持在一个单独的类中进行配置。当然,你可以选择哪些属性你想要,哪些你不需要。你也可以通过配置类中的静态方法添加新的属性。这个库最强大的功能是它支持自动将对象属性转换为DTO版本。例如

class Pojo1 {
    String a;
    Pojo b;
}

class Pojo2 {
    Pojo1 a;
    List<Pojo1> b;
    Map<List<Pojo1>>[] c;
}

@ViewOf(value = Pojo1.class, includePattern = ".*", excludes={Pojo1Meta.b})
class ConfigureOfPojo2 {}

@ViewOf(value = Pojo2.class, includePattern = ".*")
class ConfigureOfPojo2 {
    // convert b to dto version
    @OverrideViewProperty(Pojo2Meta.b)
    private List<Pojo1View> b;
    // convert c to dto version
    @OverrideViewProperty(Pojo2Meta.c)
    private Map<List<Pojo1View>>[] c;
}

将会生成

// meta class, you can use it to reference the property name in a safe way.
class Pojo1Meta {
    public final String a = "a";
    public final String b = "b";
}

// generated DTO class. The actual one will be more complicate, there are many other method.
class Pojo1View {
    private String a;
    public Pojo1View read(Pojo1 source) { ... }
    ... getters and setters ...
}

class Pojo2Meta {
    public final String a = "a";
    public final String b = "b";
    public final String c = "c";
}

class Pojo2View {
    private String a;
    private List<Pojo1View> b;
    private Map<List<Pojo1View>>[] c;
    public Pojo1View read(Pojo2 source) { ... }
    ... getters and setters ...
}

这里有趣的事情是你可以安全地使用源代码中尚不存在的类。尽管编译器可能会抱怨,但在编译后一切都会没问题。因为所有额外的类都将在编译之前自动生成。 更好的方法可能是逐步编译,首先添加@ViewOf注释,然后编译,以便生成后续需要使用的所有类。在配置完成后再次编译。其优点是IDE不会出现语法错误提示,并且可以更好地利用IDE的自动完成功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接