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();
		}
	}

你可能感兴趣的:(Hibernate多对多配置)