Spring 一对一引导 REST - POST 或 PUT?

Spring Boot REST one-to-one - POST or PUT?

我正在开发Spring Boot REST api,现在遇到了一些logical problem.

所以我有一个实体“A”,它与实体“B”具有一对一的关系。 最初,实体“A”POST没有实体“B”(-> 所以关系为空)。

所以当我想添加实体“B”时,我应该简单地 POST 它,还是 PUT/PATCH 实体“A”和实体“B”?

使用 ORM(例如 HibernatePOST/PUT/PATCHHTTP 动词在数据库中持久化实体之间没有任何关系。请不要混淆。

假设您将实体 A 和 B 定义为一对一的双向关联(默认情况下关联的(在本例中为一对​​一)optional 属性为真):

@Entity
public class A implements Serializable {

    private static final long serialVersionUID = -7174277851973636756L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(mappedBy = "a") //If you add optional = false, it will not work
    B b;

    //And so on
}


@Entity
public class B implements Serializable {

    private static final long serialVersionUID = -6581935686158784727L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne
    @JoinColumn(name = "id") //You need this, else it will look for "a_id" column(foreign_key) in Class/Table B.
    A a;

   //And so on
}

而ARepository和BRepository如下:

public interface ARepository extends CrudRepository<A, Long> {

}

public interface BRepository extends CrudRepository<B, Long> {

}

你可以简单地先做:

@Autowired
private ARepository aRepository;

A a = new A();
aRepository.save(a);
    

以后:

@Autowired
private BRepository bRepository;

B b = new B();
bRepository.save(b);

等效的 SQL:

insert 
into
    a
    (id) 
values
    (?)

insert 
into
   b
    (id) 
values
    (?)

注意: 如果该实体已经存在,save 将执行 update 而不是 insert,但由于我们使用的是自动生成的 ID,它总是会执行 insert

考虑一个实体的 A 和 B,并取 firstName 和 lastName 字段:

@Entity
public class A {

    @Id
    private Integer id;

    private String firstName;

    @OneToOne(mappedBy = "a")
    private B b; 
}

@Entity
public class B {

    @Id
    private Integer id;
 
    private String lastName;

    @OneToOne
    private A a;
}

存储库是:

@Repository 
 public interface ARepo extends JpaRepository<A,Integer> {
}
@Repository
 public interface BRepo extends JpaRepository<B,Integer> {
}

让我们使用@postContruct 在实体A中保存一些数据

@PostConstruct
void init(){
    A a = new A(1,"ABCD");
    aRepo.save(a);
}

保存B实体的控制器:

 @PostMapping("/saveB")
 public String save(@RequestBody B b){
    bRepo.save(b);
    return "ok";
 }

和json用于保存B实体:

{ “编号”:1, “姓氏”:“xyz”, “一种”:{ “编号”:1 } }

据我了解,如果我们从 B 存储库中保存实体,我们需要使用 @PostMapping(插入新行),或者我们可以使用 A 存储库保存 B 实体,因为这里的映射是双向的, 通过@PutMapping(数据库中已经存在A的数据,我们需要通过添加B的数据来更新它)