应该使用实体类作为请求主体吗?



假设我必须保存一个实体,在本例中为Book。我有下一个代码:

@RestController
@RequestMapping("books")
public class BookController {

@Inject
BookRepository bookRepository;

@PostMapping
public Book saveBook(@RequestBody Book book) {
return bookRepository.save(book);
}
}

我的实体Book是一个持久性实体:

@Entity(name = "BOOK")
public class Book{
@Id
@Column(name = "book_id")
private Integer id;
@Column(name = "title")
private String title;
(get/sets...)
}

问题是:在控制器层的@RequestBody中使用我的持久性实体是一种不好的做法吗?还是应该创建一个book DTO并将其映射到服务层中的持久性类?什么是更好的,为什么?

您应该创建一个DTO类并将其映射到持久性类。请参考此规则描述。指定的原因是

如果将持久对象用作带@RequestMapping注释的方法的参数,则可以通过特制的用户输入,将意外字段的内容更改为数据库

除此之外,使用DTO我们可以省略一些我们不希望在表示层中出现/可见的持久对象属性。

你可以像下面这样把DTO类映射到控制器本身的持久化实体。

@RestController
@RequestMapping("books")
public class BookController {

@Autowired
BookRepository bookRepository;
@Autowired
ModelMapper modelMapper

@PostMapping
public Book saveBook(@RequestBody BookDTO modelBook) {
Book book = this.modelMapper.map(modelBook, Book.class);
return bookRepository.save(book);
}
}

ModelMapper是一个框架,它执行DTO到实体的映射,反之亦然。查看ModelMapper网站。

您可以参考答案和评论来了解更多相同的信息。

是的,这是一个非常糟糕的主意。

实体表示数据库中维护的持久数据,并封装企业范围的业务规则。另一方面,DTO是一个哑对象——它只持有属性,有getter和setter,但没有其他任何重要的逻辑。dto仅用于将数据从应用程序的一个子系统传输到另一个子系统。

想象有一个新的需求来添加一个新的多对多关系:

@Entity(name = "BOOK")
public class Book{
@Id
@Column(name = "book_id")
private Integer id;
@ManyToMany
Set<Student> likes;
... 
} 

数据库的改变也会改变API。

最新更新