Hibernate(四)多对多

一个人可以买多种商品,一种商品可以被多个人所购买。

一个学生可以选多门课程,一个课程可以被多个学生选择。

一个老师可以带多个班级,一个班级可以被多个老师带。这些都是多对多的关系。

以老师和班级为例。要建立两者之间的关系需要三张表。一张老师表,一张班级表,还需要一张用来维护关系的中间表。

知道三张表之间的关系后就可以着手写代码了。


1、先建实体类。建一个教师的实体类和一个班级的实体类。给定各自所有的属性,并在教师实体类中给定一个set集合用来存放班级信息。在班级实体类中给定一个set集合用来存放教师信息。并给定set、get方法。

package cn.otote.entity;

import java.util.Set;

public class Teacher {

	private Integer id;
	
	private String name;
	
	//用于存放班级信息的set
	private Set<Classes> classesSet;

	public Integer getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public Set<Classes> getClassesSet() {
		return classesSet;
	}

	public void setClassesSet(Set<Classes> classesSet) {
		this.classesSet = classesSet;
	}
	
}
package cn.otote.e
ntity;

import java.util.Set;

public class Classes {

	private Integer id;
	
	//班级名称
	private String  className;
	//用于存放教师信息的set
	private Set<Teacher> teacherSet;

	public Integer getId() {
		return id;
	}

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

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public Set<Teacher> getTeacherSet() {
		return teacherSet;
	}

	public void setTeacherSet(Set<Teacher> teacherSet) {
		this.teacherSet = teacherSet;
	}
	
	
}

 


2、配置Teacher的映射文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- package为实体类所在的包名 -->        
<hibernate-mapping package="cn.otote.entity">
	
    <class name="Teacher" table="t_teacher" >
    
        <id name="id" column="id">
        	<!-- class="native"将主键id设为自增 -->
            <generator class="native"/>
        </id>

        <property name="name" ></property>
        
        <!-- name为存放另一方的set名称 table为中间表的表名 -->
        <set name="classesSet" table="t_teacher_classes">
        
        	<!-- key为当前表在中间表的外键 当前表是t_teacher 所以中间表的外键是t_id -->
        	<key column="t_id"></key>
        	<!-- 配置多对多 class为另一方的类型 column为另一方在中间表的外键 另一方为班级classes所以外键为c_id -->
        	<many-to-many class="Classes" column="c_id"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

3、配置Classes的映射文件,两者恰好相反。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- package为实体类所在的包名 -->        
<hibernate-mapping package="cn.otote.entity">
	
    <class name="Classes" table="t_classes" >
    
        <id name="id" column="id">
        	<!-- class="native"将主键id设为自增 -->
            <generator class="native"/>
        </id>

        <property name="className" column="class_name" ></property>
        
        <!-- name为存放另一方的set名称 table为中间表的表名 -->
        <set name="teacherSet" table="t_teacher_classes">
        
        	<!-- key为当前表在中间表的外键 当前表是t_classes 所以中间表的外键是c_id -->
        	<key column="c_id"></key>
        	<!-- 配置多对多 class为另一方的类型 column为另一方在中间表的外键 另一方为班级teacher所以外键为t_id -->
        	<many-to-many class="Teacher" column="t_id"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

4、在hibernate.cfg.xml将两个映射文件加进去。


5、测试

@Test
	void test() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		Transaction transaction = session.beginTransaction();
		
		//创建两个班级
		Classes classes1=new Classes();
		classes1.setClassName("初一一班");
		
		Classes classes2=new Classes();
		classes2.setClassName("初一三班");
		
		
		//创建两个老师
		Teacher teacher1=new Teacher();
		teacher1.setName("张老师");
		
		Teacher teacher2=new Teacher();
		teacher2.setName("李老师");
		
		
		//默认是双方都维护关系  但是只要一方维护关系就可以了 这里通过教师这一方来维护关系
		teacher1.setClassesSet(new HashSet<>());
		Set<Classes> classesSet1 = teacher1.getClassesSet();
		//将两个班级都放到第一个老师的set集合中
		classesSet1.add(classes1);
		classesSet1.add(classes2);
		
		
		teacher2.setClassesSet(new HashSet<>());
		Set<Classes> classesSet2 = teacher2.getClassesSet();
		//将两个班级都放到第二个老师的set集合中
		classesSet2.add(classes1);
		classesSet2.add(classes2);
		
		//保存数据
		session.save(classes1);
		session.save(classes2);
		session.save(teacher1);
		session.save(teacher2);
		
		//提交事务
		transaction.commit();
		
	}

运行完打开数据库可以发现三张表都已经建立好了,中间表的外键也都设置好了。再看数据,教师表和班级表的数据都已经插入,中间表的数据也维护好了。

中间表的外键:

 

教师表:

 

班级表:

中间表数据:

 


需要注意的是多对多默认是双方都维护关系的,所以我们只需要维护一方的关系就行了,如果操作时双方都维护的话会报错。当然也可以通过设置反转来让一方维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值