基于给定JSON在Spring Boot(JPA为ORM)中创建Modal类的方法
在Spring Boot中基于给定JSON创建JPA实体类的实现方案
嘿,我来帮你把这个JSON结构转换成Spring Boot里的JPA实体类。首先得拆解这个JSON的层级:它是一个主配置对象,包含一个dutyDetails数组,而每个dutyDetails又嵌套了timeSlot数组。所以咱们需要创建三个实体类来对应这个结构,下面是具体实现步骤:
1. 主实体类:DoctorDutyConfig
这个类对应JSON的最外层对象,包含顶层字段和dutyDetails列表。注意用JPA的注解标记实体、主键,还有一对多的关联关系。
import jakarta.persistence.*; import com.fasterxml.jackson.annotation.JsonManagedReference; import java.util.List; @Entity @Table(name = "doctor_duty_configs") public class DoctorDutyConfig { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // 主键,数据库自增 private Integer createdBy; private Integer hospitalId; private Integer doctorId; private Integer advanceBookingDays; // 一对多关联DutyDetail, cascade设置为ALL方便级联操作,orphanRemoval=true删除孤儿实体 @OneToMany(mappedBy = "doctorDutyConfig", cascade = CascadeType.ALL, orphanRemoval = true) @JsonManagedReference // 解决JSON序列化循环引用 private List<DutyDetail> dutyDetails; // 无参构造函数(JPA必须) public DoctorDutyConfig() {} // Getter和Setter方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Integer getCreatedBy() { return createdBy; } public void setCreatedBy(Integer createdBy) { this.createdBy = createdBy; } public Integer getHospitalId() { return hospitalId; } public void setHospitalId(Integer hospitalId) { this.hospitalId = hospitalId; } public Integer getDoctorId() { return doctorId; } public void setDoctorId(Integer doctorId) { this.doctorId = doctorId; } public Integer getAdvanceBookingDays() { return advanceBookingDays; } public void setAdvanceBookingDays(Integer advanceBookingDays) { this.advanceBookingDays = advanceBookingDays; } public List<DutyDetail> getDutyDetails() { return dutyDetails; } public void setDutyDetails(List<DutyDetail> dutyDetails) { this.dutyDetails = dutyDetails; } }
2. 子实体类:DutyDetail
对应JSON里的dutyDetails数组元素,包含自身字段和timeSlot列表,同时维护和主实体的双向关联。
import jakarta.persistence.*; import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonManagedReference; import java.time.LocalDate; import java.util.List; @Entity @Table(name = "duty_details") public class DutyDetail { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Integer tokenLimit; private LocalDate date; // 注意JSON里第二个dutyDetails元素多了这个字段,这里也加上 private Integer advanceBookingDays; // 多对一关联主实体,nullable=false表示必须关联主实体 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "doctor_duty_config_id", nullable = false) @JsonBackReference // 和主实体的JsonManagedReference配对,解决循环引用 private DoctorDutyConfig doctorDutyConfig; // 一对多关联TimeSlot @OneToMany(mappedBy = "dutyDetail", cascade = CascadeType.ALL, orphanRemoval = true) @JsonManagedReference private List<TimeSlot> timeSlot; // 无参构造函数 public DutyDetail() {} // Getter和Setter方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Integer getTokenLimit() { return tokenLimit; } public void setTokenLimit(Integer tokenLimit) { this.tokenLimit = tokenLimit; } public LocalDate getDate() { return date; } public void setDate(LocalDate date) { this.date = date; } public Integer getAdvanceBookingDays() { return advanceBookingDays; } public void setAdvanceBookingDays(Integer advanceBookingDays) { this.advanceBookingDays = advanceBookingDays; } public DoctorDutyConfig getDoctorDutyConfig() { return doctorDutyConfig; } public void setDoctorDutyConfig(DoctorDutyConfig doctorDutyConfig) { this.doctorDutyConfig = doctorDutyConfig; } public List<TimeSlot> getTimeSlot() { return timeSlot; } public void setTimeSlot(List<TimeSlot> timeSlot) { this.timeSlot = timeSlot; } }
3. 最内层实体类:TimeSlot
对应JSON里的timeSlot数组元素,包含时间段的开始和结束时间,同时维护和DutyDetail的关联。
import jakarta.persistence.*; import com.fasterxml.jackson.annotation.JsonBackReference; import java.time.LocalTime; @Entity @Table(name = "time_slots") public class TimeSlot { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private LocalTime startTime; private LocalTime endTime; // 多对一关联DutyDetail @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "duty_detail_id", nullable = false) @JsonBackReference private DutyDetail dutyDetail; // 无参构造函数 public TimeSlot() {} // Getter和Setter方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public LocalTime getStartTime() { return startTime; } public void setStartTime(LocalTime startTime) { this.startTime = startTime; } public LocalTime getEndTime() { return endTime; } public void setEndTime(LocalTime endTime) { this.endTime = endTime; } public DutyDetail getDutyDetail() { return dutyDetail; } public void setDutyDetail(DutyDetail dutyDetail) { this.dutyDetail = dutyDetail; } }
一些关键注意点:
- 主键和生成策略:每个实体都加了
@Id和@GeneratedValue(strategy = GenerationType.IDENTITY),用数据库自增主键,适合大多数场景。 - 关联关系:用
@OneToMany和@ManyToOne建立双向关联,mappedBy指定维护关联的一方在子实体,cascade = CascadeType.ALL表示对主实体的操作会级联到子实体(比如保存主实体时自动保存子实体)。 - JSON序列化:用
@JsonManagedReference和@JsonBackReference解决双向关联导致的JSON循环序列化问题,避免StackOverflowError。 - 日期时间类型:用Java 8的
LocalDate和LocalTime,Spring Boot 2.x及以上版本的JPA已经默认支持这些类型的持久化,不需要额外配置。 - 无参构造函数:JPA要求每个实体必须有无参构造函数,所以一定要加上。
内容的提问来源于stack exchange,提问作者Praphul S Sreedhar
相关产品推荐
相关产品推荐

