jpa雙向多對多關係,jpa雙向多對關係
多對多關係相比其他其中關聯關係,顯得稍微複雜了一點點,這個複雜度主要體現在對這種關聯關係的理解上。和其他關聯關係不同的是這種關聯多出來了一張中間表,操作上多了些許複雜,來隨便看下吧
1 實體的定義
Student表:
package org.lxh.info;import java.util.*;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.ManyToMany;@Entitypublic class Student {private Integer id;private String name;private Set<Teacher> teachers;@Id@GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Column(length = 50)public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToMany(cascade=CascadeType.REFRESH)@JoinTable(name="student_teacher",inverseJoinColumns=@JoinColumn(name="teacherId"),joinColumns=@JoinColumn(name="stuId"))public Set<Teacher> getTeachers() {return teachers;}public void setTeachers(Set<Teacher> teachers) {this.teachers = teachers;}}
@ManyToMany表示多對多關聯,對於這種關聯極少數情況會使用串聯刪除,我這裡設定的是級聯重新整理;因為有中間表的存在這裡使用@JoinTable來設定關聯表後面的name配置的是關聯表的名稱,inverseJoinColumn配置的是關係被維護一方主鍵對應的中間表欄位,joinColumn配置的是關係維護方主鍵對應的中間表欄位。這裡是最複雜的地方
Teacher表:
package org.lxh.info;import java.util.*;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.ManyToMany;@Entitypublic class Teacher {private Integer id;private String name;private Set<Student> students; @Id @GeneratedValuepublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;} @Column(length=50)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;}}
到這裡實體就定義完了,要注意的地方就是只有關係維護的一方才能更新中間表裡的外鍵記錄。如果反過來則會報錯
2 多對多資料儲存
/** * 雙向多對多儲存 */@org.junit.Testpublic void testMany2ManyInsert() {EntityManager em=null;EntityTransaction tx=null;try{em=JpaUtil.getEntityManager();tx=em.getTransaction();tx.begin();Student s=new Student();s.setName("張小華");Student s2=new Student();s2.setName("陳小明");Set<Student> students=new HashSet<Student>();students.add(s);students.add(s2);Teacher t=new Teacher();t.setName("李老師");t.setStudents(students);Teacher t2=new Teacher();t2.setName("劉老師");t2.setStudents(students);Set<Teacher> teachers=new HashSet<Teacher>();teachers.add(t);teachers.add(t2);s.setTeachers(teachers);s2.setTeachers(teachers); em.persist(s); em.persist(s2); em.persist(t); em.persist(t2); tx.commit();}catch(Exception e){e.printStackTrace();}finally{if(em!=null){em.close();}}}儲存操作是比較簡單的,但是如果要刪除或解除關聯關係,就稍顯複雜了,來看這段代碼
@org.junit.Testpublic void testMany2ManyDelete() {EntityManager em=null;EntityTransaction tx=null;try{em=JpaUtil.getEntityManager();tx=em.getTransaction();tx.begin();Student s=em.find(Student.class, 1);Student s2=em.find(Student.class, 2);Teacher t=em.find(Teacher.class, 2);//先解除關聯關係s.getTeachers().remove(t);s2.getTeachers().remove(t);//解除關聯關係後才能通過關係被維護端刪除資料 em.remove(t);tx.commit();}catch(Exception e){e.printStackTrace();}finally{if(em!=null){em.close();}}}
最後總結一下使用關聯關係的要點:分清楚關係維護端和關係被維護端、合理的使用註解、級聯的設定根據具體情況指定。
JPA一對多雙向關聯查詢問題
在cascade=CascadeTpe.ALL後面添加fetch=FetchType.EAGER,即主動抓取映射的類
怎配置Hibernate多對多關係 雙向
Users 的Pojo:
public Set popedom = new HashSet();
public Set getPopedom() {
return popedom;
}
public void setPopedom(Set popedom) {
this.popedom = popedom;
}
Users 的對應檔:
<set name="Popedom" table="Users_Popedom">
<key column="UsersId"/>
<many-to-many class="com.seipher.pojo.systemSet.Popedom" column="PopedomId"/>
</set>
========================================
Popedom的Pojo:
public Set UsersManage = new HashSet();
public Set getUsersManage() {
return UsersManage;
}
public void setUsersManage(Set usersManage) {
UsersManage = usersManage;
}
Popedom的對應檔:
<set name="UsersManage" table="Users_Popedom">
<key column="PopedomId"/>
<many-to-many class="com.seipher.pojo.systemSet.UsersManage" column="UsersId"/>
</set>
這兩不就是hibernate的多對多雙向關係?多對多有了,雙向監管也有了。
具體代碼操作:
/**
* 為使用者添加許可權,即使用者和許可權的關係
*
* @param yhxxid
* @param xtqxid
*/
public void setPopedom(String yhxxid, String[] xtqxid) throws HibernateException {
session = HibernateSession.hdSession();
UsersManage usersManage = (UsersManage) this.load(yhxxid);
usersManage.getPopedom().clear();
List result = new ArrayList();
for (int i = 0; i < xtqxid.length; i++) {
......餘下全文>>