首页 > 解决方案 > 从服务方法返回实体是一种不好的做法?

问题描述

我听说当你想从服务方法返回一些对象时,你必须定义一个 DTO 对象(或使用 JSON Schema 生成的 POJO 对象)而不是使用实体。

为了清楚起见,这里是一个例子:

我们有一个实体和一个 jpa 存储库:

@Data
@Entity
@Table(name = "tables")
public class Table {
    @Id
    private Long id;
    private String brand;
}

这是一个不好的做法:

@Service
public class MyService {
    @Autowired
    private TableRepository tableRepository;

    @Transactional
    public Table create() {
        Table table = new Table();
        // Some logic for creating and saving table
        return table;
    }
}

这是一个很好的做法:

@Service
public class MyService {
    @Autowired
    private TableRepository tableRepository;

    @Transactional
    public TableDTO create() {
        Table table = new Table();
        // Some logic for creating and saving table
        // Logic for converting Table object to TableDTO object
        return tableDTO;
    }
}

为什么会这样?

谢谢!

标签: javaspringspring-boot

解决方案


可能您的意思是 DTO(数据传输对象),而不是 DAO(数据访问对象)。让我澄清一下:

数据传输对象:

表示一条信息的 Pojo。通常它包含聚合数据。

数据访问对象:

执行对某种持久性存储以检索信息的访问的对象,有人认为它是 Repository 的同义词,而另一些人则不是。

实体:

表示已从数据库中检索到的数据的对象。

为什么从服务返回实体被认为是一种不好的做法?

原因是实体是非常接近数据库的东西。它包含主键,有人可以从中猜测您的数据库结构,并且查询时的数据集可能很冗长。因此,最好有某种逻辑,通常是一个映射器,它隐藏主键并聚合数据以减少冗长并且不暴露数据库结构。此外,虽然实体是建立在表结构上的,但 DTO 可以根据调用者的需要进行定制。通常它包含某些操作所需的数据,仅此而已。假设您有调用后端服务的第三方软件:您不应该将数据库结构(实体)暴露给该服务。最好定义一个合同,其中包含此第三方服务运行所需的最少信息,

希望现在更清楚一点。

编辑:当然,使用 DTO 而不是实体还有其他充分的理由,这只是对该主题的介绍性解释。


推荐阅读