日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java jpa @joincolumn 字段不为空_拥抱开源从表设计到 JPA 实现

發布時間:2024/8/1 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java jpa @joincolumn 字段不为空_拥抱开源从表设计到 JPA 实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

long?may?the?sunshine.

今天的我拿起鍵盤就是猛敲代碼。

果然,十分鐘后各種 JPA 報錯開始了。跟新手黨一樣,看到一個錯誤就解決一個,沒有好好思考為什么會出現這樣的錯誤。

于是乎,遇到一個解決一個,解決一個又遇到一個,經過數十個報錯的來回起伏。

敏銳的我發現苗頭有些不對。全靠腦細胞的記憶,以及開始對第一個錯誤的解決過程開始模糊不清了。

最后,我采用了《數據庫 ER 圖》的方式,重新開始分析、梳理。

也就是本文的初衷。

當我寫到最后的時候。我的 Junit 用例全部跑通了。贊。

以下是正文,稍微有點。。。。。。。。。。。。。長。


01 數據庫?ER 圖

ER 圖概念

  • 實體 entity:用矩形表示,數據模型中的數據對象。

  • 屬性 attribute:用橢圓形表示,數據對象所具有的屬性(所具有的列)。其中唯一屬性 unique attribute,用下劃線表示。

  • 關系 relationshop:用菱形表示,數據對象與數據對象之間的聯系。

  • 假設有兩個實體集 A、B,它們有以下三種關聯關系。

  • 一對一 1:1

  • A 的每個實體至多與 B 的一個實體有關系。

  • B 的每個實體至多與 A 的一個實體有關系。

  • 滿足以上兩點,即 A 與 B 的關系是一對一。

  • 一對多?1:N

  • A 的每個實體至少與 B 的 N(N>0)個實體有關系。

  • B 的每個實體至多與 A 的一個實體有關系。

  • 滿足以上兩點,即 A 與 B 的關系是一對多,B 與 A 的關系是多對一。

  • 多對多?M:N

  • A 的每個實體至少與 B 的 M(M>0)個實體有關系。

  • B 的每個實體至少與 A 的 N(N>0)個實體有關系。

  • 滿足以上兩點,即 A 與 B 的關系是多對多。


  • 02 JPA 關聯

    在 JPA 中分別使用 @OneToOne、@OneToMany、@ManyToOne、@ManyToMany 注解表示一對一、一對多,多對一、多對多三種關聯關系。

    OneToOne

  • targetEntity,作為關聯目標的實體類。

  • cascade,必須級聯到關聯目標的操作。

  • ALL,級聯所有操作。

  • PERSIST,級聯保存操作。

  • MERGE,級聯修改操作。

  • REMOVE,級聯刪除操作。

  • REFRESH,級聯刷新操作。

  • DETACH,級聯分離操作。(2.0 版本開始支持)

  • fetch,關聯是延遲加載還是必須立刻獲取。

  • optional,關聯是否為可選。

  • mappedBy,擁有關系的字段。僅在關聯的反側(非所有權)指定此元素。

  • orphanRemoval,是否將刪除操作應用于已從關系中刪除的實體,以及是否將刪除操作級聯到那些實體。

  • OneToMany

    targetEntity、cascade、fetch、mappedBy、orphanRemoval

    ManyToOne

    targetEntity、cascade、fetch、orphanRemoval

    ManyToMany

    targetEntity、cascade、fetch、mappedBy

    在以上關聯注解的使用過程中,還需要?@JoinColumn 指定實體關聯、元素集合的列。

    例如:@ManyToOne@JoinColumn(name="ADDR_ID")public Address getAddress() { return address; }@OneToMany@JoinColumn(name="CUST_ID")public?SetgetOrders()?{return?orders;}
    03 分析

    圖 A -?ER 圖

    本案例有四張數據庫表,分別為導購員、商品數據、訂單主數據,以及訂單明細數據。(如上圖所示)

    導購員、商品數據是基礎數據表,即不主動關聯其他的實體集。

    商品主數據,包含兩種關聯關系。

  • 與導購員之間的關系是多對一。即 @ManyToOne,注意這里只需要級聯刷新操作即可。

  • 與訂單明細數據的關系是一對多。即@OneToMany,注意這里需要級聯保存、修改、刪除、刷新所有的操作。

  • 商品明細數據,也包含兩種關聯關系。

  • 與商品數據之間的關系是多對一。即 @ManyToOne,注意這里只需要級聯刷新操作即可。

  • 與訂單主數據的關系是多對一。即@ManyToOne,注意這里需要級聯保存、修改、刪除、刷新所有的操作。


  • 04?示例代碼

    導購數據?UscGuideEntity

    package cn.live.opos.center.entity;// 省略 import/** * usc_guide. * * @author chenxinjie * @date 2020-08-01 */@Entity@Table(name = "usc_guide", uniqueConstraints = { @UniqueConstraint(columnNames = "no") })public class UscGuideEntity implements Serializable { private static final long serialVersionUID = -5648617800765002770L; @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "jpa-uuid") @GenericGenerator(name = "jpa-uuid", strategy = "org.hibernate.id.UUIDGenerator") @Column(name = "id", length = 36) private String id; @Column(name = "no", length = 20, nullable = false) private String no; @Column(name = "name", length = 40, nullable = false) private String name; @Column(name = "gender", columnDefinition = "int default 0", nullable = false) private int gender; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Temporal(TemporalType.TIMESTAMP) @Column(name = "ts", columnDefinition = "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()", nullable = false) private Date ts;??//?省略?get/set?方法}

    商品數據?PscSkuEntity

    package cn.live.opos.center.entity;// 省略 import@Entity@Table(name = "psc_sku", uniqueConstraints = { @UniqueConstraint(columnNames = "sku") })public class PscSkuEntity implements Serializable { private static final long serialVersionUID = 8904367725209990433L; @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "jpa-uuid") @GenericGenerator(name = "jpa-uuid", strategy = "org.hibernate.id.UUIDGenerator") @Column(name = "id", length = 36) private String id; @Column(name = "sku", length = 50, nullable = false) private String sku; @Column(name = "product_no", length = 40, nullable = false) private String productNo; @Column(name = "product_name", length = 100, nullable = false) private String productName; @Column(name = "color_no", precision = 4, scale = 0, nullable = false) private int colorNo; @Column(name = "color_name", nullable = false) private String colorName; @Column(name = "size_no", precision = 4, scale = 0, nullable = false) private int sizeNo; @Column(name = "size_name", nullable = false) private String sizeName; @Column(name = "tag_price", precision = 10, scale = 0, nullable = false) private int tagPrice; @Column(name = "retail_price", precision = 10, scale = 0, nullable = false) private int retailPrice; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Temporal(TemporalType.TIMESTAMP) @Column(name = "ts", columnDefinition = "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()", nullable = false) private Date ts; // 省略 get/set 方法}

    訂單主數據?OscOrderEntity

    package cn.live.opos.center.entity;// 省略 import@Entity@EntityListeners(AuditingEntityListener.class)@Table(name = "osc_order", uniqueConstraints = { @UniqueConstraint(columnNames = "order_no") })public class OscOrderEntity implements Serializable { private static final long serialVersionUID = -4409502876337140593L; @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "jpa-uuid") @GenericGenerator(name = "jpa-uuid", strategy = "org.hibernate.id.UUIDGenerator") @Column(name = "id", length = 36) private String id; @Column(name = "order_no", length = 40, nullable = false) private String orderNo; @CreatedDate @JsonFormat(pattern = "yyyy-MM-dd") @Temporal(TemporalType.DATE) @Column(name = "order_date", nullable = false) private Date orderDate; /** * 1: sell of goods. 2: return of goods. */ @Column(name = "order_type", nullable = false) private int orderType; @Column(name = "order_status", nullable = false) private int orderStatus; @Column(name = "num", precision = 5, scale = 0, nullable = false) private int num; @Column(name = "total", precision = 10, scale = 0, nullable = false) private int total; @Column(name = "guide_no", length = 20, nullable = false) private String guideNo; @LastModifiedDate @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Temporal(TemporalType.TIMESTAMP) @Column(name = "ts", columnDefinition = "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()", nullable = false) private Date ts; @OneToMany(targetEntity = OscOrderItemEntity.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "order_no", referencedColumnName = "order_no", insertable = false, updatable = false) private List orderItems; @ManyToOne(targetEntity = UscGuideEntity.class, cascade = CascadeType.REFRESH) @JoinColumn(name = "guide_no", referencedColumnName = "no", insertable = false, updatable = false) private UscGuideEntity guideEntity; // 省略 get/set 方法}

    訂單明細數據?OscOrderItemEntity

    package cn.live.opos.center.entity;// 省略 import@Entity@EntityListeners(AuditingEntityListener.class)@Table(name = "osc_order_item", uniqueConstraints = { @UniqueConstraint(columnNames = { "order_no", "sku" }) })public class OscOrderItemEntity implements Serializable { private static final long serialVersionUID = -7331381906879927968L; @Id @GeneratedValue(strategy = GenerationType.AUTO, generator = "jpa-uuid") @GenericGenerator(name = "jpa-uuid", strategy = "org.hibernate.id.UUIDGenerator") @Column(name = "id", length = 36) private String id; @Column(name = "order_no", length = 40, nullable = false) private String orderNo; @Column(name = "sku", length = 50, nullable = false) private String sku; @Column(name = "num", precision = 5, scale = 0, nullable = false) private int num; @Column(name = "tag_price", precision = 10, scale = 0, nullable = false) private int tagPrice; @Column(name = "retail_price", precision = 10, scale = 0, nullable = false) private int retailPrice; @Column(name = "total", precision = 10, scale = 0, nullable = false) private int total; @LastModifiedDate @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @Temporal(TemporalType.TIMESTAMP) @Column(name = "ts", columnDefinition = "timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() ON UPDATE CURRENT_TIMESTAMP()", nullable = false) private Date ts; @ManyToOne(targetEntity = OscOrderEntity.class, cascade = CascadeType.ALL) @JoinColumn(name = "order_no", referencedColumnName = "order_no", insertable = false, updatable = false) private OscOrderEntity orderEntity; @ManyToOne(targetEntity = PscSkuEntity.class, cascade = CascadeType.REFRESH) @JoinColumn(name = "sku", referencedColumnName = "sku", insertable = false, updatable = false) private PscSkuEntity skuEntity;??// 省略 get/set 方法}

    05 效果

    使用 JPA 查詢一個訂單主數據,JPA 會自動將配置好的其他表的數據實體自動查詢出來。

    也就是,省略了查詢導購員、訂單明細數據、商品數據三條?SQL 語句。

    PS. 完整示例代碼,見?https://github.com/FoamValue/oPos.git


    06?小結

    今天先寫到這里。

    夜深了,讓我們下周再見。?

    這個周末,又一次成功“強迫”自己學習。

    感謝各位小伙伴的閱讀,這里是一個技術人的學習與分享。

    總結

    以上是生活随笔為你收集整理的java jpa @joincolumn 字段不为空_拥抱开源从表设计到 JPA 实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。