我被分配了这个作业,只是为了练习,它变得非常漫长且具有挑战性,但它教会了我很多东西,主要是关于 lambda 和 JPA。
它是一个基本的Rest API,用于创建酒店、房间、客人、预订、客人类型、房间类型等。
我最初的问题是学习 JPA 关系、OneToOne、OneToMany 等、单向、双向等等。
我也在使用 PostgreSQL,使用"sping.jpa.hibernate.ddl-auto=create-drop(or update)"
,当我出于某种原因想要重新创建数据库时,根据需要进行更改。
因此,我非常高兴和兴奋使用我的新 @Annotations 来关联我的实体,并取回我需要的任何信息的列表,遇到了多个问题,在这里阅读了很多问题,解决了我的问题,但现在我遇到了一个新问题,但随后,开始质疑我的方法,也许我不应该把一切都留给 JPA。
让我告诉你我的意思。我将保持我的课程简短,只显示相关信息。
我有我的预订实体。
@Data
@Entity
@Table(name = "reservation")
public class Reservation {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "guest", referencedColumnName = "id")
@JsonManagedReference
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private Guest guest;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "room", referencedColumnName = "id")
private Room room;
@ManyToMany(fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
@JoinTable(name = "reservation_rooms",
joinColumns = { @JoinColumn(name = "reservation_id" )},
inverseJoinColumns = { @JoinColumn(name = "room_id") }
)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private List<ReservationRoom> roomList = new ArrayList<>();
private LocalDate start_date;
private LocalDate end_date;
private Boolean check_in;
private Boolean check_out;
public void addRoom(Room room) {
this.roomList.add(room);
}
public void removeRoom(Long id) {
Room room = this.roomList.stream().filter(g -> g.getId() == id).findFirst().orElse(null);
if (room != null) {
this.roomList.remove(room);
}
}
}
这是我的房间实体。
@Data
@Entity
@Table(name = "room")
public class Room {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String description;
private Integer floor;
@JsonProperty("max_guests")
private Integer maxGuests;
@ManyToOne(fetch = FetchType.LAZY)
@JsonBackReference
private Hotel hotel;
@ManyToOne(fetch = FetchType.LAZY)
@JsonProperty("type")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private RoomType roomType;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Room)) {
return false;
}
return id != null && id.equals(((Room) o).getId());
}
@Override
public int hashCode() {
return getClass().hashCode();
}
}
这是我的访客实体。
@Data
@Entity
@Table(name = "guest")
public class Guest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String first_name;
private String last_name;
private String email;
@ManyToOne(fetch = FetchType.LAZY)
@JsonProperty("type")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private GuestType guest_type;
@ManyToMany(fetch = FetchType.LAZY,
cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
},
mappedBy = "guestList"
)
@JsonBackReference
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
private List<Reservation> reservationList = new ArrayList<>();
public Guest(){}
public Guest(Long id) {
this.id = id;
}
public List<Reservation> getReservationList() {
return reservationList;
}
public void setReservationList(List<Reservation> reservationList) {
this.reservationList = reservationList;
}
}
一开始预订只能有一个房间,但要求改变了,现在可以有多个房间。因此,现在,客人列表需要链接到与预订关联的房间,而不是直接链接到预订。(我知道我有一位客人和一间房间,还有两者的列表,这是因为我使用单个客人作为预订名称,并使用单个房间作为“主”房间,但不要请不要介意)。
抛开 JPA 不谈,因为我遇到的每一个挑战都会问自己“JPAish 该怎么做?”,然后研究如何用 JPA 来做(这就是我了解 @ManyToMany 等注释的方式)。
我要做的只是创建一个新表,将预订与房间关联起来(这已经在我的实体中使用 JPA 完成),然后添加客人 ID。
因此,这个新表将与reservation_id、room_id 和guest_id 进行PK。非常简单,然后创建我的预订模型,其中有一个房间列表,而这个房间模型将有一个客人列表。简单的。
但我不想在当前的房间实体中添加宾客列表,因为我有一个端点,可能还有几个其他函数,它们会检索我的房间实体,并且我不想添加宾客列表,因为随着时间的推移,这个列表会变得越来越大,这是你不需要传递的信息。
因此,我做了一些研究,发现我可以使用 @Inheritance 或 @MappedSuperclass 扩展我的实体,并且我可以创建一个 Reservation_Room 模型,其中包括宾客列表并添加 Reservation_Room 列表,而不是我的预订中的房间列表实体,我真的不知道它是否可能。
话虽如此,在我继续研究并开始修改我的代码之前,我想知道这是否是正确的方法?或者我是否在这方面对 JPA 施加了太多压力?最好的方法是什么?可以在 JPA 上轻松实现/映射 3 id 关系表吗?
主要目标是让我的房间实体按原样公开,但是当将房间添加到预订中时,该房间还将有一个客人列表。我可以做这个 JPAish 吗?或者我应该创建一个新模型并根据需要填充信息?这并不能免除我创建 3 个 ids 表的责任。