Hibernate 双向多对多拆分成两个一对多

Posted ztca

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate 双向多对多拆分成两个一对多相关的知识,希望对你有一定的参考价值。

1.双向多对多:B(Teacher)有多个A(Student),A也有多个B

注意要在一方加上inverse属性,否则一起维护关联关系可能会造成主键冲突:

 package roadArchitectWeb;  

  1. import java.util.HashSet;  
  2. import java.util.Set;  
  3. public class Teacher {  
  4. private Integer Id;  
  5. private String Name;  
  6. private String PhoneNum;  
  7. private Set<Student> Students = new HashSet<>();  
  8. public Set<Student> getStudents() {  
  9. return Students;  
  10.     }  
  11. public void setStudents(Set<Student> students) {  
  12.         Students = students;  
  13.     }  
  14. public Integer getId() {  
  15. return Id;  
  16.     }  
  17. public void setId(Integer id) {  
  18.         Id = id;  
  19.     }  
  20. public String getName() {  
  21. return Name;  
  22.     }  
  23. public void setName(String name) {  
  24.         Name = name;  
  25.     }  
  26. public String getPhoneNum() {  
  27. return PhoneNum;  
  28.     }  
  29. public void setPhoneNum(String phoneNum) {  
  30.         PhoneNum = phoneNum;  
  31.     }  
  32. public  Teacher() {  
  33.     }  
  34. @Override  
  35. public String toString() {  
  36. return "Teacher [Id=" + Id + ", Name=" + Name + ", PhoneNum=" + PhoneNum + ", Students=" + Students + "]";  
  37.     }  
  38. }  

 

 


 
  1. package roadArchitectWeb;  
  2.   
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.   
  6. public class Student {  
  7.     private Integer Id;  
  8.     private String sName;  
  9.     private String Age;  
  10.     private Set<Teacher> Teachers = new HashSet<>();  
  11.     public Set<Teacher> getTeachers() {  
  12.         return Teachers;  
  13.     }  
  14.     public void setTeachers(Set<Teacher> teachers) {  
  15.         Teachers = teachers;  
  16.     }  
  17.     public Integer getId() {  
  18.         return Id;  
  19.     }  
  20.     public void setId(Integer id) {  
  21.         Id = id;  
  22.     }  
  23.     public String getsName() {  
  24.         return sName;  
  25.     }  
  26.     public void setsName(String sName) {  
  27.         this.sName = sName;  
  28.     }  
  29.     public String getAge() {  
  30.         return Age;  
  31.     }  
  32.     public void setAge(String age) {  
  33.         Age = age;  
  34.     }  
  35.     @Override  
  36.     public String toString() {  
  37.         return "Student [Id=" + Id + ", sName=" + sName + ", Age=" + Age + ", Teachers=" + Teachers + "]";  
  38.     }  
  39.     public Student(){  
  40.     }  
  41. }  

 
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  4. <!-- Generated 2016-4-21 19:12:13 by Hibernate Tools 3.5.0.Final -->  
  5. <hibernate-mapping package="roadArchitectWeb">  
  6.     <class name="Student" table="STUDENT">  
  7.         <id name="Id" type="java.lang.Integer">  
  8.             <column name="ID" />  
  9.             <generator class="native">  
  10.             </generator>  
  11.         </id>  
  12.         <property name="sName" type="java.lang.String">  
  13.             <column name="SNAME" />  
  14.         </property>  
  15.         <property name="Age" type="java.lang.String">  
  16.             <column name="AGE" />  
  17.         </property>  
  18.        <set name="Teachers" table="teacher_student" inverse="true">  
  19.         <key column="studentId"></key>  
  20.         <many-to-many column="teacherId" class="Teacher"></many-to-many>  
  21.         </set>  
  22.     </class>  
  23. </hibernate-mapping>  

 
  1. <?xml version="1.0"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  4. <!-- Generated 2016-4-21 19:12:13 by Hibernate Tools 3.5.0.Final -->  
  5. <hibernate-mapping package="roadArchitectWeb">  
  6.     <class name="Student" table="STUDENT">  
  7.         <id name="Id" type="java.lang.Integer">  
  8.             <column name="ID" />  
  9.             <generator class="native">  
  10.             </generator>  
  11.         </id>  
  12.         <property name="sName" type="java.lang.String">  
  13.             <column name="SNAME" />  
  14.         </property>  
  15.         <property name="Age" type="java.lang.String">  
  16.             <column name="AGE" />  
  17.         </property>  
  18.        <set name="Teachers" table="teacher_student" inverse="true">  
  19.         <key column="studentId"></key>  
  20.         <many-to-many column="teacherId" class="Teacher"></many-to-many>  
  21.         </set>  
  22.     </class>  
  23. </hibernate-mapping>  
 
  1. package roadArchitectWeb;  
  2. import org.hibernate.Session;  
  3. import org.hibernate.SessionFactory;  
  4. import org.hibernate.Transaction;  
  5. import org.hibernate.cfg.Configuration;  
  6. import org.junit.Test;  
  7.   
  8. import com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor;  
  9. public class HibernateTest {  
  10.     @Test  
  11.     public void test() {  
  12.         SessionFactory sessionFactory = null;  
  13.         Configuration configuration = new Configuration().configure();  
  14.         sessionFactory = configuration.buildSessionFactory();  
  15.         Session session = sessionFactory.openSession();  
  16.         Transaction transaction = session.beginTransaction();  
  17.           
  18.         /*begin*/  
  19.         Teacher teacher = new Teacher();  
  20.         Student student = new Student();  
  21.         teacher.setName("chenT");  
  22.         teacher.setPhoneNum("18788837117");  
  23.         student.setsName("ma");  
  24.         student.setAge("11");  
  25.           
  26.         student.getTeachers().add(teacher);  
  27.         teacher.getStudents().add(student);  
  28.           
  29.         session.save(student);  
  30.         session.save(teacher);  
  31.           
  32. //      student = (Student)session.get(Student.class, 1);  
  33. //      teacher = (Teacher)session.get(Teacher.class,1);  
  34. //      System.out.println("HibernateTest.test()S:"+student.getTeacher().getName());  
  35. //      System.out.println("HibernateTest.test()T:"+teacher.getStudents().size());  
  36.           
  37.         transaction.commit();  
  38.         session.close();  
  39.         sessionFactory.close();  
  40.     }  
  41. }  

这个时候的双向多对多,数据库会生成一个关联表,里面有且只有两个类的外键。  

 

2.多对多拆分两个一对多

针对上面那个情况,因为自动生成的关联表中只有两个外键这两个列,如果我想在这个列种存放其他属性怎么办? 因为关联表是自动生成的,这个时候的解决办法就是把多对多的关联关系改为两个一对多双向关联。  举个例子:

一个订单有多种商品,种个商品可能在多个订单里。但是我如果描述一个订单里一种商品的数量该怎么描述,必须建立一个订单-商品关联表,然后在关联表中设置商品的数量,这样一条记录就代表一个订单,一种商品和这个商品的数量。

那应该如何实现呢?   把订单当作一,把商品当作一,把关系表(这个关系表与订单以及商品一样是通过一个类生成的,而不是hibernate自动生成)当作多,并且建立两个一对多的双向关联关系,就可以实现。 

代码实现按照之前的一对多双向示例即可。

以上是关于Hibernate 双向多对多拆分成两个一对多的主要内容,如果未能解决你的问题,请参考以下文章

SSH框架整合截图

Hibernate,关系映射的多对一单向关联多对一双向关联一对一主键关联一对一外键关联多对多关系关联

hibernate 双向多对多映射关系

Hibernate—— 一对多 和 多对多关联关系映射(xml和注解)总结(转载)

hibernate 一对多双向的问题~~~

hibernate------映射相关