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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

JPA规范:一对多、一对一、多对多的双向关联与级联操作以及JPA联合主键

發布時間:2024/9/30 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JPA规范:一对多、一对一、多对多的双向关联与级联操作以及JPA联合主键 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通常在企業開發中,開發Dao層有兩種做法:?
(1)先建表,后再根據表來編寫配置文件和實體bean。使用這種方案的開發人員受到了傳統數據庫建模的影響。?
(2)先編寫配置文件和實體bean,然后再生成表,使用這種方案的開發人員采用的是領域建模思想,這種思想相對前一種思想更加OOP。

建議使用第二種(領域建模思想),從軟件開發來想,這種思想比第一種思想更加面向對象。 領域建模思想也是目前比較新的一門建模思想,第一種是傳統的建模思想,已經有10來年的發展歷程了,而領域建模思想是近幾年才興起的,這種思想更加的面向對象。

?

?

一、一對多雙向關聯與級聯操作:

以訂單類和訂單商品類為例:

多的一方為關系維護端,關系維護端負責外鍵記錄的更新,關系被維護端是沒有權利更新外鍵記錄。

1、訂單類:

@Entity public class Orders {private String orderid;private Float amount = 0f;private Set<OrderItem> items=new HashSet<OrderItem>();@Id @Column(length=12)public String getOrderid() {return orderid;}public void setOrderid(String orderid) {this.orderid = orderid;}@Column(nullable=false)public Float getAmount() {return amount;}public void setAmount(Float amount) {this.amount = amount;}//REFRESH,級聯刷新(調用refresh方法才會起作用);PERSIST,級聯保存(persist);//MERGE,級聯更新(merge方法);REMOVE,級聯刪除(remove方法);//級聯:cascade={CascadeType.ALL})如果要使用上面四項的使用,可以使用ALL來代替//@OneToMany默認行為是延遲加載//mappedBy:指定關系被維護端,指定OrderItem里面的order,相當于hibernate的inverse放棄維護@OneToMany(cascade={CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},fetch=FetchType.LAZY,mappedBy="orders")public Set<OrderItem> getItems() {return items;}public void setItems(Set<OrderItem> items) {this.items = items;}public void addOrderItem(OrderItem orderItem){orderItem.setOrders(this);this.items.add(orderItem);} }

2、訂單列表類:

@Entity public class OrderItem {private Integer id;private String productName;private Float sellPrice = 0f;private Orders orders;//對應Order類里面指定的關系被維護端@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=40,nullable=false)public String getProductName() {return productName;}public void setProductName(String productName) {this.productName = productName;}@Column(nullable=false)public Float getSellPrice() {return sellPrice;}public void setSellPrice(Float sellPrice) {this.sellPrice = sellPrice;}//默認立即加載//optional=true,選項允許為null,false時,不能為null@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)@JoinColumn(name="order_id")//設置外鍵名稱public Orders getOrders() {return orders;}public void setOrders(Orders orders) {this.orders = orders;} }

3、一對多的測試類:

//JPA的Dao層 @Transactional public class JpaDaoImpl implements JpaDao {//事務管理@PersistenceContextprivate EntityManager em;//JPA一對多測試類@Overridepublic void jpaTest() {Orders orders=new Orders();orders.setAmount(34f);orders.setOrderid("999");OrderItem orderItem1=new OrderItem();orderItem1.setProductName("籃球");orderItem1.setSellPrice(150f);OrderItem orderItem2=new OrderItem();orderItem2.setProductName("足球");orderItem2.setSellPrice(90f);orders.addOrderItem(orderItem1);orders.addOrderItem(orderItem2);em.merge(orders);} }

由于配置了事務管理,這里就不需要手動開啟、提交事務和關閉資源等重復的代碼,直接交由事務進行管理。

具體配置步驟可以參看這篇博客:https://blog.csdn.net/a745233700/article/details/81415550

?

?

二、一對一雙向關聯與級聯操作:

以身份證類和人為例:

1、Persion類:

@Entity public class Person {public Person() {}public Person(String name) {this.name=name;}private Integer id;private String name;private IDcard idcard;@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=10,nullable=false)public String getName() {return name;}public void setName(String name) {this.name = name;}//一對一配置@OneToOne(optional=false,cascade={CascadeType.ALL})@JoinColumn(name="idcard_id")public IDcard getIdcard() {return idcard;}public void setIdcard(IDcard idcard) {this.idcard = idcard;} }

2、IDcard類:

@Entity public class IDcard {public IDcard() {}public IDcard(String cardno) {this.cardno = cardno;}private Integer id;private String cardno;private Person person;@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=18,nullable=false)public String getCardno() {return cardno;}public void setCardno(String cardno) {this.cardno = cardno;}//一對一配置:@OneToOne(mappedBy="idcard",cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH})public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;} }

3、一對一測試類:

//JPA一對多測試類@Overridepublic void jpaTest() {Person person=new Person("小張"); person.setIdcard(new IDcard("448xxx1990xxxx1234"));em.persist(person);}

?

?

三、多對多雙向關聯與級聯操作:

以教師類和學生類為例:

1、教師類:

//老師為關系被維護端 @Entity public class Teacher {public Teacher(){}public Teacher(String name) {this.name = name;}private Integer id;private String name;private Set<Student> students=new HashSet<Student>();@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=10,nullable=false)public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teachers")public Set<Student> getStudents() {return students;}public void setStudents(Set<Student> students) {this.students = students;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((id == null) ? 0 : id.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Teacher other = (Teacher) obj;if (id == null) {if (other.id != null)return false;} else if (!id.equals(other.id))return false;return true;} }

2、學生類:

//學生為關系維護端 @Entity public class Student {public Student(){}public Student(String name) {this.name = name;}private Integer id;private String name;private Set<Teacher> teachers=new HashSet<Teacher>();@Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length=10,nullable=false)public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToMany(cascade=CascadeType.REFRESH)@JoinTable(name="student_teacher",//設置第三張表的表名inverseJoinColumns=@JoinColumn(name="teacher_id"),//設置被維護端在第三張表中的外鍵名稱joinColumns=@JoinColumn(name="student_id"))//設置維護端在第三張表中的外鍵名稱public Set<Teacher> getTeachers() {return teachers;}public void setTeachers(Set<Teacher> teachers) {this.teachers = teachers;}public void addTeacher(Teacher teacher){this.teachers.add(teacher);}public void removeTeacher(Teacher teacher){if(this.teachers.contains(teacher)){this.teachers.remove(teacher);}} }

3、多對多測試類:

//JPA多對多測試類:沒有建立關系聯系的添加@Overridepublic void jpaTest() {//沒有建立關系聯系的添加em.persist(new Student("小張"));em.persist(new Teacher("李老師"));} //JPA多對多測試類:建立學生跟老師的聯系@Overridepublic void jpaTest() {//建立學生和老師的關系Student student=em.find(Student.class, 15);student.addTeacher(em.getReference(Teacher.class, 16));} //JPA多對多測試類:刪除學生跟老師的聯系@Overridepublic void jpaTest() {//刪除學生跟老師的聯系Student student=em.find(Student.class, 15);student.removeTeacher(em.getReference(Teacher.class, 16));} //JPA多對多測試類:刪除對象:只刪除教師//直接不接觸外鍵,直接刪除老師,這種方式刪除不了,被維護端沒有權限刪除外鍵,拋異常@Overridepublic void jpaTest() {em.remove(em.getReference(Teacher.class, 16));} //JPA多對多測試類:刪除對象:只刪除教師//先解除學生與老師的關系,再刪除教師對象@Overridepublic void jpaTest() {Student student=em.find(Student.class, 15);Teacher teacher=em.getReference(Teacher.class, 16);student.removeTeacher(teacher);em.remove(teacher);} //JPA多對多測試類:刪除對象:學生,并刪除第三表中的記錄,不刪除老師//關系維護端有權限刪除外鍵@Overridepublic void jpaTest() {em.remove(em.getReference(Student.class, 15));}

?

?

四、聯合主鍵:

以飛機航線為例:兩個城市決定一條航線。

1、聯合主鍵的三個要求:

(1)必須定義無參構造函數;

(2)必須實現序列化接口Serializable;

(3)必須重寫hashCode()和equals()方法。

2、AirLinkPK聯合主鍵類:

/*聯合主鍵的三個要求: 1.必須定義無參構造函數 2.必須實現序列化接口Serializable 3.必須重寫hashCode()和equals()方法 */ @Embeddable public class AirLinePK implements Serializable { public AirLinePK(){}public AirLinePK(String startCity, String endCity) {this.startCity = startCity;this.endCity = endCity;}private String startCity;//開始城市private String endCity;//結束城市@Column(length=3)public String getStartCity() {return startCity;}public void setStartCity(String startCity) {this.startCity = startCity;}@Column(length=3)public String getEndCity() {return endCity;}public void setEndCity(String endCity) {this.endCity = endCity;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((endCity == null) ? 0 : endCity.hashCode());result = prime * result + ((startCity == null) ? 0 : startCity.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;AirLinePK other = (AirLinePK) obj;if (endCity == null) {if (other.endCity != null)return false;} else if (!endCity.equals(other.endCity))return false;if (startCity == null) {if (other.startCity != null)return false;} else if (!startCity.equals(other.startCity))return false;return true;} }

3、AirLine類:

@Entity public class AirLine {public AirLine(){}public AirLine(AirLinePK id) {this.id = id;}public AirLine(String startCity,String endCity,String name){this.id=new AirLinePK(startCity,endCity);this.name=name;}private AirLinePK id;private String name;//聯合主鍵的實體標識符@EmbeddedIdpublic AirLinePK getId() {return id;}public void setId(AirLinePK id) {this.id = id;}@Column(length=20)public String getName() {return name;}public void setName(String name) {this.name = name;} }

3、聯合主鍵測試類:

//聯合主鍵測試類@Overridepublic void jpaTest() {em.persist(new AirLine("PEK","SHA","北京飛上海"));}

?

?

總結

以上是生活随笔為你收集整理的JPA规范:一对多、一对一、多对多的双向关联与级联操作以及JPA联合主键的全部內容,希望文章能夠幫你解決所遇到的問題。

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