数据传输具有M:N或1:N关系的实体的对象

Kub*_*tny 5 java web-applications dto

我有2个实体 - 电影和演员 - 有M:N的关系.在为这些实体设计DTO对象时,我不确定什么是正确的方法.

电影

@Entity
@Table(name = "Movies")
public class Movie extends AbstractBusinessObject {    

    private String name;
    private String short_info;    

    @ManyToMany
    private Map<String, Actor> cast;

}
Run Code Online (Sandbox Code Playgroud)

演员

@Entity
@Table(name = "Actors")
public class Actor extends Person{

    private String name;

    @ManyToMany(mappedBy = "cast")
    private Set<Movie> movies;

}
Run Code Online (Sandbox Code Playgroud)

现在关于DTO:我遇到了两种不同的方式来处理1:N和M:N关系.

仅保存ID:

public class MovieDto {    

    private String name;
    private String short_info;    

    // Long represents Actor's ID
    private Map<String, Long> cast;

}
Run Code Online (Sandbox Code Playgroud)

然而,正如我在这里所说的那样Instead of performing many remote calls on EJBs, the idea was to encapsulate data in a value object,我认为,这种做法显然违反了规则.

在DTO中保存DTO:另一种方法是存储Actor的Dto,而不是其ID.

public class MovieDto {    

    private String name;
    private String short_info;

    private Map<String, ActorDto> cast;

}
Run Code Online (Sandbox Code Playgroud)

在我看来,这种方法会更快,因为我不必每次都需要显示演员姓名时调用数据库.

这个假设是正确的,还是只存储ID更好(甚至考虑第二种方法的空间消耗)?

另外,第二种方法会导致一个实体的许多DTO.例如,我不需要知道演员在观看"电影页面"时播放的电影,但在查看"演员页面"时我需要这样做.

Viv*_*ath 4

将其他 DTO 实例嵌入到父 DTO 中是完全可以接受的。当然,如果对象最终变得非常大,这可能会变得令人望而却步。所以这是你必须做出某种权衡的地方。

解决这个问题的一种方法是采用部分表示和完整表示。如果不需要完整数据,可以使用部分表示。如果您确实需要完整数据,则可以使用完整表示。您甚至可以拥有它,以便完整表示将部分表示嵌入其中(组合),并简单地推迟对其的调用(对于部分数据)。

我之前使用过的另一种方法是告诉我的映射器(将实体转换为 DTO)我是否需要完整数据。这样映射器就可以决定 DTO 是否需要填充附加数据。