spring-boot - spring boot 与外键一对一
问题描述
我想在我的数据库中存储房间详细信息和房间类型。我为Room创建了一个实体,如下所示。
@Data
@Entity
public class Room {
@Id
private String room_id;
private Boolean status;
private Double price;
private Long type;
private Long occupancy;
@OneToOne(fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "type_id", nullable = false)
private RoomType roomType;
}
我创建了一个 RoomType 实体,如下所示:
@Data
@Entity
public class RoomType {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String type;
}
要在我的数据库中保存房间实体,以下是需要给出的请求正文格式
{
"room_id": "string",
"status": true,
"price": 0,
"roomType": {
"id": 1,
"type": "string"
}
}
我希望请求正文如下
{
"room_id": "string",
"status": true,
"price": 0,
"roomType": 1 # This the roomType foreign key
}
我想要一对一的关系,所以在检索房间详细信息时,我也会以以下格式获取房间类型值。
{
"room_id": "string",
"status": true,
"price": 0,
"roomType": {
"id": 0,
"type": "string"
}
}
或者有没有更好的方法来处理spring boot中的此类问题?
解决方案
我认为这里有两个不同的概念:
- a 在您的服务中的内部表示
Room
(您使用的类及其关系) - 外部表示(由您的 API 公开的表示)
如果您希望这两种表示形式相同,则可以Room
直接使用该类对数据进行序列化/反序列化(我假设这是您当前正在做的事情)。例如:
@Controller
class MyController {
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public Room createRoom(@RequestBody Room room) {
// Here room will be automatically deserialized from the request body
// Do stuff with the received room in here
// ...
// Here the returned room will be automatically serialized to
// the response body
return createdRoom;
}
}
但是,如果您不希望内部和外部表示相同,则可以使用 DTO 模式(数据传输对象)。此处为 Spring 中的示例。
现在,您将拥有三个不同的类,Room
它们是 DTO:
public class RoomRequestDTO {
private String room_id;
private Boolean status;
private Double price;
private Long type;
private Long occupancy;
private Integer roomType; // This is now an Integer
// Setters and Getters ...
}
public class RoomResponseDTO {
private String room_id;
private Boolean status;
private Double price;
private Long type;
private Long occupancy;
private RoomType roomType; // This is a RoomType instance
// Setters and Getters ...
}
现在,您的控制器将接收RoomRequestDTO
s 并发送RoomResponseDTO
s:
@Controller
class MyController {
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public RoomResponseDTO createRoom(@RequestBody RoomRequestDTO roomReqDTO) {
Room room = ... // Convert from DTO to Room
// Do stuff with the received room in here
RoomResponseDTO roomRespDTO = ... // Convert to the DTO
return roomRespDTO;
}
}
这种方法还有一个优点是您现在可以更改内部表示Room
而不影响 API。也就是说,您可以决定将Room
和RoomType
类合并为一个,而不影响外部表示。
注意:在我链接的示例中,他们使用该ModelMapper
库。如果您不想引入这种依赖关系,您可以简单地向 DTO 添加一个构造函数和一个方法
public RoomResponseDTO(Room room) {
// Manually asign the desired fields in here
this.id = room.getId();
// ...
}
public Room toRoom() {
Room room = new Room();
// Manually asing the desired field in here
room.setId(this.id);
// ...
return room;
}
但是,这种方法会使您在想要更改Room
. 图书馆ModeMapper
为你做这件事。
推荐阅读
- c++ - 使用 Wininet 发送带有 UTF-8 特殊字符的 POST 消息
- python - ValueError:无法从 Pandas 中的重复轴重新索引
- ios - 在 UICollectionView 中选择多个单元格
- sql - SQL:从 3 条记录中获取数据并合并为一条
- c++ - 函数返回机制:临时对象、R-Value、L-Value
- javascript - 防止 API 返回的数据覆盖空输入 onFocus
- html - 使用带有excel数据的excel vba搜索网站,并在搜索结果的流程图中提取活动状态并将其映射到列中
- python - 不可散列的类型:制作字典时的“列表”
- python-3.x - 显着高值的一侧比例测试
- monitoring - 无接口的 Zabbix Web 监控