Hibernate级联关系映射(多对多)

还是要说一句,百度百科上的级联的概念是:级联在关联映射中是个重要的概念,指当主动方对象执行操作时,被关联对象(被动方)是否同步执行同一操作。

多对多的关系和一对多的关系类似,就是把一对多中的一变成了多。

Java对象描述多对多数据表之间的关系:

class A{
   Set<B> bs;//B的集合
}

class B{
   Set<A> as;//A的集合
}

下面Gd就以学生和课程之间的关联关系进行多对多级联关系映射的学习:

通常,为了方便维护数据,多对多的关系都会产生一张中间表,类似下图(Gd手拙,画的有点抽象),其中Student、Course和中间表s_c之间是一对多的关系。


怕同志们看不明白,Gd就为大家讲解一下上图,Student表为学生表,id为主键,sname为学生姓名;Course表为课程表,id为主键,cname为课程名称;s_c为中间表,cid和sid为外键。

图片讲解之后我们就来分析一下学生和课程之间的关系,由于一个学生可以学习多门课程,一门课程也可以被多个学生学习,所以说学生和课程之间的关系是多对多关系。这种关系需要在学生类和课程类中分别以集合Set的方式引入对方的对象,并在映射文件中通过<set>标签进行映射。

分析完毕后我们就以一个具体案例来演示Hibernate中多对多关系的使用。

首先还是要定义实体类Student.java和Course.java

1.Student.java

package cn.itcast.manytomany;

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


public class Student {

	/**
	 * @param args
	 */
	private Integer id;							   //学生id
	private String sname;							   //学生姓名
	private Set<Course>courses = new HashSet<Course>();		           //关联课程对象
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public Set<Course> getCourses() {
		return courses;
	}
	public void setCourses(Set<Course> courses) {
		this.courses = courses;
	}
	
}

2.Course.java

package cn.itcast.manytomany;

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

public class Course {

	/**
	 * @param args
	 */
	private Integer id;							//课程id
	private String cname;							//课程名称
	private Set<Student>students = new HashSet<Student>();			//关联学生对象
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getCname() {
		return cname;
	}
	public void setCname(String cname) {
		this.cname = cname;
	}
	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
	
}

接着是Student和Course类对应的映射文件:

3.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">
<!-- Generated 2017-8-22 10:37:16 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="cn.itcast.manytomany.Student" table="student">
        <id name="id" column="id" >
            <generator class="increment" ></generator>
        </id>
        <!-- 普通属性 -->
        <property name="sname" length="30"/>
        <!-- 映射Course对象,并添加中间表
             cascade属性表示级联操作:
             属性值有:
             all-代表在所有的情况下都执行级联操作;
             none-在所有的情况下都不执行级联操作,是默认值;
             save-update-在保存和更新的时候执行级联操作;
             delete-在删除的时候执行级联操作;
         -->
        <set name="courses" table="s_c" cascade="save-update">
        	<!-- 设置外键 -->
        	<key column="sid"/>
        	<!-- 多对多关系映射 -->
        	<many-to-many 
        			class="cn.itcast.manytomany.Course" column="cid"/>
        </set>
    </class>
</hibernate-mapping>

4.Course.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 2017-8-22 10:37:16 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="cn.itcast.manytomany.Course" table="course">
        <id name="id" column="id" >
            <generator class="increment" ></generator>
        </id>
        <!-- 普通属性 -->
        <property name="cname" length="30"/>
        <!-- 映射Course对象,并添加中间表 -->
        <set name="students" table="s_c">
        	<!-- 设置外键 -->
        	<key column="cid"/>
        	<!-- 多对多关系映射 -->
        	<many-to-many 
        			class="cn.itcast.manytomany.Student" column="sid"/>
        </set>
    </class>
</hibernate-mapping>

同样的,要把映射文件路径配置到xxx.cfg.xml中:

5.hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<property name="show_sql">true</property>
		<property name="hibernate.dialect">org.hibernate.dialect.Oracle9iDialect</property>
		<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
		<property name="hibernate.connection.username">system</property>
		<property name="hibernate.connection.password">123456</property>
		<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
		<property name="hibernate.hbm2ddl.auto" >create</property> 
		<!--以下两行为 一对多映射文件的关联 -->
		<mapping resource="cn/itcast/onetomany/Customer.hbm.xml"/>
		<mapping resource="cn/itcast/onetomany/Order.hbm.xml"/>
		<!-- 以下两行为新增的多对多映射文件的关联 -->
		<mapping resource="cn/itcast/manytomany/Student.hbm.xml"/>
		<mapping resource="cn/itcast/manytomany/Course.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

最后就要编写测试类了:

6.TestManyToMany

package cn.itcast.manytomany;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class TestManyToMany {
	@Test
	public void test1()
	{
		Configuration conf = new Configuration().configure();
		SessionFactory sf = conf.buildSessionFactory();
		Session session  = sf.openSession();
		Transaction tx = session.beginTransaction();
		//1.创建两个学生
		Student s1 = new Student();
		s1.setSname("张三");
		Student s2 = new Student();
		s2.setSname("李四");
		//2.创建两个科目
		Course c1 = new Course();
		c1.setCname("数据结构");
		Course c2 = new Course();
		c2.setCname("操作系统");
		//3.建立关联关系
		//学生关联科目
		s1.getCourses().add(c1);
		s2.getCourses().add(c1);
		s1.getCourses().add(c2);
		s2.getCourses().add(c2);
		//4.存储
		session.save(c1);
		session.save(c2);
		session.save(s1);
		session.save(s2);
		//提交事务,关闭Session
		tx.commit();
		session.close();
	}

}
使用Junit进行测试:

自动生成的student表:

自动生成的中间表s_c:


自动生成的course表:


至此,Gd就把多对多的级联关系学习的差不多了,希望能够帮到大家,也希望大家能够和Gd多多交流!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值