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