[英]How to properly divide business and data layer in a Spring Boot Rest Interface
I am working with Spring Boot for quite some time now but have surprinsingly not encountered this type of problem before.我现在使用 Spring Boot 已经有一段时间了,但出乎意料地以前没有遇到过这种类型的问题。
Given the following Code example:给出以下代码示例:
Parent家长
@Entity
@Table(name="Parent")
@Cacheable(true)
@OptimisticLocking(type= OptimisticLockType.VERSION)
@DynamicUpdate
public class Parent implements Serializable {
private Long id;
private Child child;
@Id
public Long getId() {
return this.id;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "child")
public Child getChild(){
return this.child;
}
}
Child孩子
@Entity
@Table(name="Child")
@Cacheable(true)
@OptimisticLocking(type= OptimisticLockType.VERSION)
@DynamicUpdate
public class Child implements Serializable {
private Long id;
private String name;
@Id
public Long getId() {
return this.id;
}
public String getName() {
return this.name;
}
Repository存储库
@Repository
public interface ParentRepository extends JpaRepository<Parent, Long> {}
Controller控制器
@RestController
public class RestController {
@Autowired
private ParentRepository parentRepository;
@RequestMapping(value="/data/parent/{parentid}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public Optional<Parent> getParent(@PathVariable("parentid") Long parentId){
return parentRepository.findById(parentId);
}
@RequestMapping(value = "/data/parent", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public Parent addParent(@RequestBody Parent parent) {
return parentRepository.save(parent);
}
The above code works fine and as expected when executing the GET method.上面的代码在执行 GET 方法时可以正常工作并且符合预期。 A result would look something like:
结果将类似于:
{
"id":1,
"child": {
"id":1,
"name":"Jesus"
}
}
However, The way I need to use the POST method is to pass only the foreign key of the children that I want to connect to my parent.但是,我需要使用 POST 方法的方式是只传递我想连接到我父母的孩子的外键。 I do not want to create a whole Child Object, serialize it into JSON and add it to the request body.
我不想创建整个子对象,将其序列化为 JSON 并将其添加到请求正文中。 Meaning I want to be able to POST a Parent object with a JSON like this:
这意味着我希望能够使用这样的 JSON 发布 Parent 对象:
{
"id":1,
"child":1
}
and let the Rest Interface to the job of fetching my Child object.并让 Rest 接口完成获取我的 Child 对象的工作。
I was able to find a way to achieve this by adding another variable我能够通过添加另一个变量找到一种方法来实现这一目标
@Transient
Long childId;
to my Parent object and then in the controller, GET the corresponding Child object first and add it to the Parent before persisting.到我的父对象,然后在控制器中,先获取相应的子对象,然后在持久化之前将其添加到父对象。
However, I am quite certain that this is not a good way to solve this problem and that the solution will include dividing my data model into two seperate layers.但是,我很确定这不是解决这个问题的好方法,解决方案将包括将我的数据模型分成两个单独的层。 Unfortunately, I have not yet been able to find out how to do this exactly.
不幸的是,我还不能确切地知道如何做到这一点。
I am thankful for any advise.我很感激任何建议。
You should divide your business model by layers : DTO
(used for data exchanging with your REST clients) and Entities
(for database operations).您应该按层划分您的业务模型:
DTO
(用于与 REST 客户端交换数据)和Entities
(用于数据库操作)。
With that seperation you have more flexibility and can POST
what you want without messing your entities with stuff like @JsonIgnore
or @Transient
.与分离-你有更多的灵活性和可
POST
你想要的东西没有用一样的东西搞乱你的实体@JsonIgnore
或@Transient
。
You will have something like:你会有类似的东西:
@PostMapping(value = "/data/parent")
public ParentDTO addParent(@RequestBody LightParentDTO parentDTO) {
return service.save(parentDTO);
}
and和
class LightParentDTO {
long parentId;
long childId;
}
Note that I introduce a service.save(...)
, there you can do all your DTO
to Entity
conversion operations.请注意,我引入了
service.save(...)
,在那里您可以执行所有DTO
到Entity
转换操作。
If I got you right, what you need to do is use the @jsonignore annotation Try this:如果我猜对了,你需要做的是使用 @jsonignore 注释试试这个:
@Entity
@Table(name="Parent")
@Cacheable(true)
@OptimisticLocking(type= OptimisticLockType.VERSION)
@DynamicUpdate
public class Parent implements Serializable {
private Long id;
@JsonIgnore <========================================================
private Child child;
@Id
public Long getId() {
return this.id;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "child")
public Child getChild(){
return this.child;
}
}
let me know if it works让我知道它是否有效
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.