Использование одного объекта DTO для проецирования - PullRequest
0 голосов
/ 03 мая 2018

У меня проблемы с использованием одного объекта DTO или объекта DTO для каждого объекта Entity. Например, у меня есть 3 класса: книга, автор и издатель.

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:

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 голосов
/ 03 мая 2018

Я уже некоторое время работаю с DTO, и вот некоторые вещи, которыми я могу поделиться:

  • Попробуйте построить иерархию DTO на основе ваших потребностей (абстрактные классы и / или интерфейсы)
  • Даже если ваш BookDTO «просто» расширяет суперкласс (например, AbstractIdDescriptionDTO), он всегда более читабелен (IMO), и его менее утомительно поддерживать, и вы не можете неправильно интерпретировать объект для другого
  • Я никогда не использую синтаксис new DTO, вместо этого я реализовал автоматический конвертер
0 голосов
/ 03 мая 2018

На мой взгляд, создайте DTO для каждого поля. Наличие одного DTO связывает ваши объекты много. Например, если в классе Book вы измените описание на что-то другое, весь ваш код больше не будет работать.

Даже если вы начнете думать о хорошем названии DTO, вы увидите проблему. «MyDTO» звучит не очень хорошо и не показывает своего предназначения, но вы не сможете придумать какое-либо значимое имя.

И, наконец, что не менее важно, есть единый принцип ответственности, который хорош, и наличие одного DTO для представления нескольких объектов как бы нарушает его. Это не очень хорошая практика и нарушает принцип SOLID, чтобы иметь один класс, который представляет разные типы объектов. Если ваши проекты имеют общие свойства, лучше иметь отдельные классы и создать интерфейс для общей части. Это просто стандартный дизайн ООП. Это не связано с DTO

Это только мое мнение. Я могу ошибаться.

Кроме того, создание DTO, подобных этому, в запросе JPQL делает его сложным и сложным в обслуживании. Вы можете сделать что-то вроде:

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

для вашего запроса или есть другие способы сделать это.

...