还是要说一句,百度百科上的级联的概念是:级联在关联映射中是个重要的概念,指当主动方对象执行操作时,被关联对象(被动方)是否同步执行同一操作。
多对多的关系和一对多的关系类似,就是把一对多中的一变成了多。
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多多交流!!!