hibernate多对多双向关联

多对多双向关联:数据库中有一张students表(字段 id和name),teachers表(字段id和name) 还有一张关联表 s_t(字段id 外键stu_id(参考students表的id)和tea_id(参考teachers表的id))

 

类图如下:Student中还存在一个teachers 的集合


hibernate多对多双向关联
 Students.java

package com.org.model;


import java.util.Set;

public class Students {
    private int id;
    private String name;
    private Set<Teacher> teachers;//多对多关系一般有一个中间表用于相关联,Hibernate面向对象,更注重于对象关系

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(Set<Teacher> teachers) {
        this.teachers = teachers;
    }

}

 Teacher.java

package com.org.model;


import java.util.Set;

public class Teacher {
    private int id;
    private String name;
    private Set<Students> students;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Students> getStudents() {
        return students;
    }

    public void setStudents(Set<Students> students) {
        this.students = students;
    }

}

 Students.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.org.model">
	<class name="Students" table="students" >
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name" not-null="true"/>
		
		<!-- set标签中的name用于指定映射的集合类型(即为Students类中多方对应的属性名 )
		       key标签中的column为s_t表中参照students表的外键-->
		<set name="teachers"  cascade="save-update" inverse="true" table="s_t">
			<key column="stu_id" not-null="true"></key>
			<!-- class表明set中放的是什么类型的集合,column指定s_t表中参照teacher表的外键 -->
			<many-to-many class="Teacher" column="tea_id"></many-to-many>      
		</set>
	</class>


</hibernate-mapping>

 Teacher.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.org.model">
	<class name="Teacher" table="teachers" >
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name" not-null="true"/>
		
		<!-- set标签中的name用于指定映射的集合类型(即为Teacher类中多方对应的属性名 )
		       key标签中的column为s_t表中参照teacher表的外键-->
		<set name="students"  cascade="save-update" table="s_t">
			<key column="tea_id" not-null="true"></key>
			<!-- class表明set中放的是什么类型的集合,column指定s_t表中参照students表的外键 -->
			<many-to-many class="Students" column="stu_id"></many-to-many>     
		</set>
	</class>


</hibernate-mapping>

 hibernate.cfg.xml

<mapping resource="com/org/model/Students.hbm.xml" />
<mapping resource="com/org/model/Teacher.hbm.xml" />

 测试类:

package com.org.model.test;

import java.util.HashSet;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.org.model.Students;
import com.org.model.Teacher;
import com.org.util.HibernateUtil;

public class HibernateTest2 {

	@Test
	public void testSave1() {
		Session session = null;
		Transaction tx = null;
		try {

			// 拿到session
			session = HibernateUtil.getSession();
			// 开启事务
			tx = session.beginTransaction();

			// 给实体赋值

			Set<Teacher> ts = new HashSet<Teacher>();
			Teacher t1 = new Teacher();
			t1.setName("XiangfGang1");
			ts.add(t1);

			Teacher t2 = new Teacher();
			t2.setName("ZhengHui1");
			ts.add(t2);

			Teacher t3 = new Teacher();
			t3.setName("WangJinFeng1");
			ts.add(t3);

			Set<Students> ss = new HashSet<Students>();
			Students sd1 = new Students();
			sd1.setName("ChengHai1");
			ss.add(sd1);

			Students sd2 = new Students();
			sd2.setName("JiangKui1");
			ss.add(sd2);

			Students sd3 = new Students();
			sd3.setName("YanJiaYang1");
			ss.add(sd3);

			t1.setStudents(ss);
			t2.setStudents(ss);
			t3.setStudents(ss);
			session.save(t1);
			session.save(t2);
			session.save(t3);
			// 告诉学生有哪些老师,与上面告诉老师有哪些学生任选一种即可
			// sd1.setTeachers(ts);
			// sd2.setTeachers(ts);
			// sd3.setTeachers(ts);
			// session.save(sd1);
			// session.save(sd2);
			// session.save(sd3);

			// 提交事务
			tx.commit();

		} catch (Exception e) {
			// 打印堆栈信息
			e.printStackTrace();
			// 事务回滚
			if (tx != null) {
				tx.rollback();
			}
		} finally {
			HibernateUtil.closeSession(session);
		}
	}

}

 结果:

Hibernate: insert into teachers (name) values (?)
Hibernate: insert into students (name) values (?)
Hibernate: insert into students (name) values (?)
Hibernate: insert into students (name) values (?)
Hibernate: insert into teachers (name) values (?)
Hibernate: insert into teachers (name) values (?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)

 因为中间表的关系由Teacher端维护,所以插入Teacher的时候会插入关联关系。只能一段来维护关系,不能两端同时维护关系,这样会导致在中间表出现重复插入的现象。

你可能感兴趣的:(Hibernate)