java - 从服务方法返回实体是一种不好的做法?
问题描述
我听说当你想从服务方法返回一些对象时,你必须定义一个 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;
}
}
为什么会这样?
谢谢!
解决方案
可能您的意思是 DTO(数据传输对象),而不是 DAO(数据访问对象)。让我澄清一下:
数据传输对象:
表示一条信息的 Pojo。通常它包含聚合数据。
数据访问对象:
执行对某种持久性存储以检索信息的访问的对象,有人认为它是 Repository 的同义词,而另一些人则不是。
实体:
表示已从数据库中检索到的数据的对象。
为什么从服务返回实体被认为是一种不好的做法?
原因是实体是非常接近数据库的东西。它包含主键,有人可以从中猜测您的数据库结构,并且查询时的数据集可能很冗长。因此,最好有某种逻辑,通常是一个映射器,它隐藏主键并聚合数据以减少冗长并且不暴露数据库结构。此外,虽然实体是建立在表结构上的,但 DTO 可以根据调用者的需要进行定制。通常它包含某些操作所需的数据,仅此而已。假设您有调用后端服务的第三方软件:您不应该将数据库结构(实体)暴露给该服务。最好定义一个合同,其中包含此第三方服务运行所需的最少信息,
希望现在更清楚一点。
编辑:当然,使用 DTO 而不是实体还有其他充分的理由,这只是对该主题的介绍性解释。
推荐阅读
- javascript - 甜蜜的警报2:如何自动对焦输入?
- java - 如何修复 API 版本 23 的 androidx 中的 FloatingActionButton 膨胀错误?
- android - 内部存储好像没有设置,怎么解决?
- android - java.lang.ClassNotFoundException 使用 OpenCV4
- php - 将 strtotime 与 TimeZone 一起使用
- java - 休眠 JSON 转换器的奇怪行为
- java - MySQL 连接器 jar 版本如何影响查询性能?
- c# - Blob 触发器:未配置存储帐户
- javascript - 大写单词的第一个字母
- twilio - 我可以在 jQuery 中使用 Twilio Video JS SDK 2.0 吗?