Spring Boot RESTful API 的层设计及其实体映射
Posted
技术标签:
【中文标题】Spring Boot RESTful API 的层设计及其实体映射【英文标题】:Design of the layers of a Spring Boot RESTful API and its entities mapping 【发布时间】:2020-08-09 10:14:12 【问题描述】:自从我使用 Spring Boot 从头开始开发我的第一个 RESTful API 以来,我一直在思考我的服务器的架构。 我正在使用 Hibernate,并使用 Hibernate/JPA 注释创建了几个实体及其关系,但是,我不确定是否应该将这些实体用作业务模型,因为它们对于 Hibernate 推荐的额外字段是“脏的”。
This is my tentative REST API layered architecture
这是一个直接取自 Hibernate 文档的示例。
@Entity(name = "Person")
public static class Person implements Serializable
@Id
@GeneratedValue
private Long id;
@NaturalId
private String registrationNumber;
@OneToMany(
mappedBy = "person",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PersonAddress> addresses = new ArrayList<>();
// ...
public void addAddress(Address address)
PersonAddress personAddress = new PersonAddress( this, address );
addresses.add( personAddress );
address.getOwners().add( personAddress );
public void removeAddress(Address address)
PersonAddress personAddress = new PersonAddress( this, address );
address.getOwners().remove( personAddress );
addresses.remove( personAddress );
personAddress.setPerson( null );
personAddress.setAddress( null );
@Entity(name = "PersonAddress")
public static class PersonAddress implements Serializable
@Id
@ManyToOne
private Person person;
@Id
@ManyToOne
private Address address;
// ...
@Entity(name = "Address")
public static class Address implements Serializable
@Id
@GeneratedValue
private Long id;
private String street;
@Column(name = "`number`")
private String number;
private String postalCode;
@OneToMany(
mappedBy = "address",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PersonAddress> owners = new ArrayList<>();
// ....
我的意思是,如果我要制作一个类图,它看起来不会与这些实体完全一样,因为您必须为 Hibernate 完成一些条件,以便它可以使用 ORM 将它们映射到表。例如,在假设的类图中,Person
将有一个 Address
列表,而不是 Hibernate 在这种情况下建议的 PersonAddress
列表(用于映射性能)。
我的问题是我是否应该将Person
模型分成两个独立的实体,一个用于业务逻辑层(服务),一个用于数据访问层(存储库)。就个人而言,我认为这不是问题,因为 Hibernate 帮助我忽略了所有的表创建,但也许这不是一个好习惯,我应该将它分成两个不同的实体。
【问题讨论】:
【参考方案1】:一般来说,我使用 API 模型和实体模型。 api模型用于在服务之间交换数据,实体对象用于持久化数据。这使您的架构更加灵活。如果您的业务逻辑中的某些内容发生更改,实体不会自动受到影响。此外,有时您通过客户端获取数据并且不想公开整个数据库对象。因此,您可以只提供您需要的字段并在实体对象中完成其余部分。这也是静态代码分析 sonaqube 推荐的。
【讨论】:
【参考方案2】:您所指的是持久性模型和业务/域模型之间的分裂,这很常见。人们通常将此称为 DTO 方法。 这种方法有很多好处,如果你实施得当,几乎没有缺点。
可以使用Blaze-Persistence Entity-Views 有效地实现它,这是一个位于 JPA/Hibernate 之上的库,它将透明地为您处理所有获取。查看spring data integration,它可以让您快速入门,或者通过archetype 试用示例项目以感受其中的好处。
【讨论】:
以上是关于Spring Boot RESTful API 的层设计及其实体映射的主要内容,如果未能解决你的问题,请参考以下文章
??????spring boot??????restful api