使用单个DTO对象进行投影

时间:2018-05-03 13:23:15

标签: java hibernate pojo dto

我无法为每个Entity对象使用单个DTO对象或DTO对象。 例如,我有3个类:Book,Author和Publisher。

Book.java

@Entity
@Table(name = "tbl_book")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "description")
    private String description;

    other different fields...
}

Author.java

@Entity
@Table(name = "tbl_author")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "description")
    private String description;

    other different fields...
}

Publisher.java

@Entity
@Table(name = "tbl_publisher")
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "description")
    private String description;

    other different fields...
}

MyDTO.java

public class MyDTO {
    private Long id;
    private String description;

    constructor id, description...
    getters and setters...
}

我想用EntityManager选择特定字段(id和description):

em.createQuery("SELECT NEW MyDTO(id,description) FROM Book");

但我的问题是我应该为所有投影使用单个DTO对象(即MyDTO)吗?类似的东西:

em.createQuery("SELECT NEW MyDTO(id,description) FROM Author");
em.createQuery("SELECT NEW MyDTO(id,description) FROM Publisher");

关于使用DTO进行投影的教程只是说使用DTO进行读取并使用Entity进行写入,但他们没有说明是否有单个对象DTO。请您提供一个示例,说明为什么单个DTO或为什么DTO适用于每个实体。谢谢!

2 个答案:

答案 0 :(得分:2)

我已经与DTO合作了一段时间了,这里有一些我可以分享的内容:

  • 尝试根据您的需求(抽象类和/或接口)构建DTO层次结构
  • 即使您的data.frame(df1[rep(1:nrow(df1), lengths(lst)), 1:2], YearMonth = format(do.call(c, lst), "%Y%m")) 只是'扩展了一个超类(例如BookDTO),它总是更具可读性(IMO),并且维护起来不那么繁琐,而且你不能将一个对象误解为另一个
  • 我从不使用AbstractIdDescriptionDTO语法,而是实现了自动转换器

答案 1 :(得分:1)

在我看来,为每个领域创建一个DTO。拥有一个DTO可以很好地耦合您的对象。例如,如果在Book类中将描述更改为其他内容,则所有代码将不再起作用。

即使你开始考虑DTO的好名字,你也会看到问题所在。 “MyDTO”听起来并不好,并没有表明其目的,但你无法想到一个有意义的名字。

最后但并非最不重要的是,单一责任原则是一件好事,并且有一个DTO可以提供多个对象来打破它。这不是一个好习惯,并且打破了SOLID原则,让一个类代表不同类型的对象。如果您的项目共享一些公共属性,最好有单独的类并为公共部分创建一个接口。这只是标准的OOP设计。它与DTO无关

这只是我的意见。我可能错了。

同样创建类似于JPQL查询类型的DTO,使其难以编码且难以维护。你可以这样做:

.setResultTransformer( Transformers.aliasToBean( PostDTO.class ) ) 

您的查询或其他方法。