JPA中@OneToOne 与 @OneToMany 的用法

Spring工程中,创建实体对象时,可以通过JPA的@Entity标识实体与数据库表的对应关系,@Column标识数据库字段。其中还有标识两个实体间关系的注解:@OneToOne、@OneToMany、@ManyToOne和@ManyToMany,分别标识一对一、一对多、多对一和多对多。在此,简单记录下@OneToOne和@OneToMany的使用。其中还会涉及注解@JoinColumn,其修饰的字段为关系维护字段。

@OneToOne

  @OneToOne与@JoinColumn结合使用,表示会在源实体(Source Entity,即声明该注解的实体类中创建外键,进行级联),以ShipOrderInfo和ShipOrderRecords为例。

  • ShipOrderInfo类,会在ship_order_info表中创建ship_order_records的外键;
  • ShipOrderRecords类,mappedBy = "shipOrderInfo",表示由ShipOrderInfo类的shipOrderRecordsList维护外键;
  • 保存ShipOrderInfo对象的时候,会先将ShipOrderRecords对象保存,然后设置ShipOrderInfo对象外键,并保存。即先保存targetEntity,设置外键后,再保存sourceEntity

@OneToMany

  @OneToMany与@JoinColumn结合使用,会在目标实体(targetEntity指定的类中创建外键)。保存的时候,先保存sourceEntity,设置外键后,再保存targetEntity。如ShipOrderRecords 和 ShipOrdedLogs是一对多的情况。

@Data
@Entity(name = "ShipOrderInfo")
@Table(name = "ship_order_info")
public class ShipOrderInfo extends AuditModel implements Serializable {

    private static final long serialVersionUID = -3984010638987217501L;

    @Id
    @GeneratedValue(
            strategy = GenerationType.AUTO,
            generator = "pg-uuid"
    )
    @GenericGenerator(
            name = "pg-uuid",
            strategy = "uuid2",
            parameters = @org.hibernate.annotations.Parameter(
                    name = "uuid_gen_strategy_class",
                    value = "com.decathlon.shiphub.common.util.PostgreSQLUUIDGenerationStrategy"
            )
    )
    @Column(name = "id", columnDefinition = "uuid default uuid_generate_v4()")
    private UUID id;

    @Column(name = "ship_group_id")
    @NotEmpty(message = "ship_group_id must not be empty")
    private String shipGroupId;

    @Column(name = "order_id")
    private String orderId;

    @Column(name = "tracking_number")
    private String trackingNumber;

    @Column(name = "estimated_delivery_time", columnDefinition = "timestamptz")
    private Instant estimatedDeliveryTime;

    @Column(name = "real_delivery_time", columnDefinition = "timestamptz")
    private Instant realDeliveryTime;

    @Column(name = "order_paytime", columnDefinition = "timestamptz")
    private Instant orderPaytime;

    @Column(name = "sports_user_id")
    private String sportsUserId;

    @Column(name = "client_channel")
    private Integer clientChannel;

    @Column(name = "label_url")
    private String labelURL;

    @Column(name = "b2c_order_id")
    private String b2cOrderId;

    @Column(name = "order_latest_status")
    private Integer orderLatestStatus;

    @Column(name = "data_status", columnDefinition = "int2 default 0")
    private Byte dataStatus;

    @Column(name = "carrier_id")
    private UUID carrierId;

    @Column(name = "location_info_id")
    private UUID locationInfoId;

    @Column(name = "delivery_type")
    private String deliveryType;

    @Column(name = "contact_phone")
    private String contactPhone;

    @Column(name = "order_platform")
    private String orderPlatform;

    @Column(name = "click_collect_destination")
    private String clickCollectDestination;

    @Column(name = "order_sequence")
    private String orderSequence;

    @OneToOne(mappedBy = "shipOrderInfo", cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JsonManagedReference
    private List<ShipOrderRecords> shipOrderRecordsList;
}

 

@Data
@Entity(name = "ShipOrderRecords")
@Table(name = "ship_order_records")
public class ShipOrderRecords extends AuditModel implements Serializable {

    private static final long serialVersionUID = -6873931504419257515L;

    @Id
    @GeneratedValue(
            strategy = GenerationType.AUTO,
            generator = "pg-uuid"
    )
    @GenericGenerator(
            name = "pg-uuid",
            strategy = "uuid2",
            parameters = @org.hibernate.annotations.Parameter(
                    name = "uuid_gen_strategy_class",
                    value = "com.decathlon.shiphub.common.util.PostgreSQLUUIDGenerationStrategy"
            )
    )
    @Column(name = "id", columnDefinition = "uuid default uuid_generate_v4()")
    private UUID id;

    @Column(name = "ship_status", columnDefinition = "int2 default 0")
    private int shipStatus;

    @Column(name = "reason_code")
    private String reasonCode;

    @Column(name = "comment")
    private String comment;

    @Column(name = "data_status", columnDefinition = "int2 default 0")
    private Byte dataStatus;

    @OneToMany(mappedBy = "shipOrderRecords", cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    @JsonManagedReference
    private List<ShipOrderLogs> shipOrderLogsList;

    @OneToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "order_info_id")
    @JsonBackReference
    private ShipOrderInfo shipOrderInfo;
}
@Data
@Entity(name = "ShipOrderLogs")
@Table(name = "ship_order_logs")
public class ShipOrderLogs extends AuditModel implements Serializable {

    private static final long serialVersionUID = 7671064435799278019L;

    @Id
    @GeneratedValue(
            strategy = GenerationType.AUTO,
            generator = "pg-uuid"
    )
    @GenericGenerator(
            name = "pg-uuid",
            strategy = "uuid2",
            parameters = @org.hibernate.annotations.Parameter(
                    name = "uuid_gen_strategy_class",
                    value = "com.decathlon.shiphub.common.util.PostgreSQLUUIDGenerationStrategy"
            )
    )
    @Column(name = "id", columnDefinition = "uuid default uuid_generate_v4()")
    private UUID id;

    @Column(name = "request_body", length = 3000)
    private String requestBody;

    @Column(name = "response_body", length = 3000)
    private String responseBody;

    @Column(name = "log_desc")
    private String logDesc;

    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name = "order_records_id")
    @JsonBackReference
    private ShipOrderRecords shipOrderRecords;
}

需要注意的是:

  (1)多对多情况,可以不用这种注解的方式,可以通过中间表维护级联关系(比如A和B表多对多,C表只包含2列A和B的主键映射,维护多对多关系),操作可能更方便。

  (2)这种级联谨慎使用,在查询等操作的时候,查A实体,也会把级联的B或C实体也查出来,但业务只需要A的信息,所以可能增加数据库负担。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值