You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于给定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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:07:44