1. 程式人生 > >Hibernate多對多配置

Hibernate多對多配置

一、多對多

              只需配置兩個實體類及對映檔案,除兩個實體表外,自動生成第三方中間表。

二、配置實體類

              在entity包下新增Student類、Teacher類、

  public class Student {
	private Integer id;
	private String name;
	private Set<Teacher> teachers = new HashSet<Teacher>();

	//get、set方法

	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + "]";
	}

}
  
public class Teacher {
	private Integer id;
	private String name;
	private Set<Student> students = new HashSet<Student>();
        //get、set方法
	@Override
	public String toString() {
		return "Teacher [id=" + id + ", name=" + name + ", students=" + students + "]";
	}

}

三、配置對映檔案

       Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
    <class name="Student" table="STUDENT">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <!-- table:中間第三方表(兩者相同)
             key子元素的column:name:集合外來鍵(引用當前表主鍵的那個外來鍵)   -->
        <set name="teachers" table="TEACHER_STUDENT" inverse="false">
            <key>
                <column name="studentId" />
            </key>
            <many-to-many class="Teacher" column="teacherId"/>
        </set>
    </class>
</hibernate-mapping>
      Hibernate.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-4-21 15:50:50 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="entity">
    <class name="Teacher" table="TEACHER">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <set name="students" table="TEACHER_STUDENT" inverse="true">
            <key>
                <column name="teacherId" />
            </key>
            <many-to-many class="Student" column="studentId"/>
        </set>
    </class>
</hibernate-mapping>

四、測試類
@Test
	public void testSave() {
		Session session = DBManager.getSessionFactory().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();

			Teacher teacherA = new Teacher();
			teacherA.setName("TA");

			Teacher teacherB = new Teacher();
			teacherB.setName("TB");

			Student studentA = new Student();
			studentA.setName("SA");
			
			Student studentB = new Student();
			studentB.setName("SB");

			/*teacherA.getStudents().add(studentA);
			teacherA.getStudents().add(studentB);
			teacherB.getStudents().add(studentA);
			teacherB.getStudents().add(studentB);*/
			
			//將Student類中的set的inverse設為false,關聯其中的teacherSet與teacher,操作第三方表
			studentA.getTeachers().add(teacherA);
			studentA.getTeachers().add(teacherB);
			studentB.getTeachers().add(teacherA);
			studentB.getTeachers().add(teacherB);

			session.save(teacherA);
			session.save(teacherB);
			session.save(studentA);
			session.save(studentB);

			tx.commit();
		} catch (HibernateException e) {
			tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	
	@Test
	public void testGet(){
		Session session = DBManager.getSessionFactory().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			//設定inverse="true"只改變關聯關係修改,不影響查詢
			Teacher teacher = (Teacher) session.get(Teacher.class, 1);
			System.out.println(teacher);
			tx.commit();
		} catch (HibernateException e) {
			tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	
	@Test
	public void testRemoveRelation(){
		Session session = DBManager.getSessionFactory().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			//解除關聯關係需使用inverse為false的類,刪除中間表資訊
			Student student = (Student) session.get(Student.class, 1);
			student.getTeachers().clear();
			tx.commit();
		} catch (HibernateException e) {
			tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}
	
	@Test
	public void testDelete(){
		Session session = DBManager.getSessionFactory().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			//inverse為false,先刪除中間表資訊,在刪除本身
			Student student = (Student) session.get(Student.class, 2);
			session.delete(student);
			
			/*inverse為ture,未刪除中間表,直接刪除本身,由於外來鍵關聯而報錯
			Teacher teacher = (Teacher)session.get(Teacher.class, 3);
			session.delete(teacher);*/
			
			tx.commit();
		} catch (HibernateException e) {
			tx.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
	}