问题描述
我有一个用例,其中有两种用户,即“客户”和“专业人士”。这两个实体都有一个称为“用户”的父实体,其中每个“用户”根据其角色在“客户/专业”中都有一个条目。
让我们考虑一个“客户”。
- “用户”与“客户端”具有一对一映射
- 客户下面可能有几个“公司”,即“客户”与“公司”具有一对多关系。
我正在使用Spring Boot为此用例创建一个REST API。我仍然不知道为什么我应该在Hibernate中使用映射。到目前为止,我看到的唯一优点是它的CASCADING属性。如果删除了“用户”,则所有具有“用户ID”的表也将被刷新。但是考虑一种情况,我需要为“客户”添加“公司”。我对应该通过“客户”实体坚持“公司”还是应该直接对“客户”实体坚持感到困惑。我看不到任何主要优势,因为在两种情况下,我们都在持久存储在“客户”表中之前检查是否存在具有给定ID的“客户”。
用户实体
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long UID;
private Integer userRoleId;
private String username;
private String email;
private String phoneNumber;
private String firstName;
private String lastName;
private Long dateOfJoin;
private Boolean activeStatus;
private Long createdAt;
private Long updatedAt;
@OnetoOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy = "user")
private Client client;
}
客户实体
public class Client {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long CID;
@Column(unique = true)
private Long userId;
private Long createdAt;
private Long updatedAt;
@OnetoOne(cascade = CascadeType.ALL,mappedBy = "client")
private ClientCompany clientCompany;
@OnetoOne(cascade = CascadeType.ALL)
@JoinColumn(name = "userId",referencedColumnName = "UID",insertable = false,updatable = false)
private User user;
}
客户公司实体
public class ClientCompany {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long CCID;
private Long clientId;
private String email;
private String phoneNumber;
public String streetAddress1;
public String streetAddress2;
public String zipCode;
public String city;
public String state;
public String country;
private Long createdAt;
private Long updatedAt;
@OnetoOne(cascade = CascadeType.ALL)
@JoinColumn(name = "clientId",referencedColumnName = "CID",updatable = false)
private Client client;
}
解决方法
使用Hibernate / JPA的优点是您不需要编写JDBC调用代码。 您只使用对象。 在您的情况下,
- 从数据库加载客户端实例;
- 创建一个ClientCompany对象;
- 将Client实例分配给它(由于您是从数据库中加载的,因此无需检查客户端是否存在);
- 保存到数据库。
无需编写任何SQL语句,Hibernate就能处理一切。
步骤1)也可以替换为创建一个新客户端,该客户端将被保存到数据库中,但是Hibernate同样会正确处理保存(如果配置正确)。