Hibernate 映射多对多关联关系

多对多持久化类和映射文件的搭建

1.创建持久化类

1.创建Student类

这里写图片描述

package cn.itcast.hibernate0909.manytomany;

import java.io.Serializable;
import java.util.Set;

public class Student implements Serializable{
    private Long sid;
    private String sname;
    private String description;

    private Set<Course> course;
    public Long getSid() {
        return sid;
    }

    public void setSid(Long sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Set<Course> getCourse() {
        return course;
    }

    public void setCourse(Set<Course> course) {
        this.course = course;
    }

}

1.创建Course类

这里写图片描述

package cn.itcast.hibernate0909.manytomany;

import java.io.Serializable;
import java.util.Set;

public class Course implements Serializable{
    private Long cid;
    private String cname;

    private String description;

    private Set<Student> students;

    public Long getCid() {
        return cid;
    }

    public void setCid(Long cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

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

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


}

2.配置映射文件

1.配置Student.hbm.xml映射文件

<?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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="cn.itcast.hibernate0909.manytomany.Student">
        <id name="sid" type="java.lang.Long" length="5">    
            <column name="sid"></column>
            <generator class="increment"></generator>
        </id>

        <property name="sname" type="java.lang.String" length="50"></property>

        <property name="description" type="java.lang.String" length="50"></property>

        <!-- 
            table 指的是多对多的第三张表
         -->
        <set name="course" table="student_course" cascade="save-update">
            <key>
                <column name="sid"></column>
            </key>
            <many-to-many class="cn.itcast.hibernate0909.manytomany.Course" column="cid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

这里写图片描述

2.配置Course.hbm.xml映射文件

<?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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="cn.itcast.hibernate0909.manytomany.Course">
        <id name="cid" type="java.lang.Long" length="5">    
            <column name="cid"></column>
            <generator class="increment"></generator>
        </id>

        <property name="cname" type="java.lang.String" length="50"></property>

        <property name="description" type="java.lang.String" length="50"></property>

        <!-- 
            table 指的是多对多的第三张表
         -->
        <set name="students" table="student_course" cascade="save-update" inverse="true">
            <key>
                <column name="cid"></column>
            </key>
            <many-to-many class="cn.itcast.hibernate0909.manytomany.Student" column="sid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

这里写图片描述

2.配置hibernate.cfg.xml文件

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!-- 是用来描述数据库的连接 -->
<session-factory>
    <!-- 
        驱动
    -->
    <property name="connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <!-- 
        url
    -->
    <property name="connection.url">
        jdbc:mysql://localhost:3306/hibernate0909
    </property>
    <!-- 
        username
    -->
    <property name="connection.username">root</property>
    <!-- 
        password
    -->
    <property name="connection.password">123</property>
    <!-- 
        hibernate针对建表的操作
        update  如果有表,检查表的结构,如果没有则创建
        create-drop 启动hibernate创建表,结束hibernate删除表
        create  每次启动都重新创建表
        validate 每次启动都检查表的结构
    -->
    <property name="hbm2ddl.auto">update</property>
    <property name="show_sql">true</property>
    <mapping
        resource="cn/itcast/hibernate0909/manytomany/Course.hbm.xml" />
    <mapping
        resource="cn/itcast/hibernate0909/manytomany/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>

多对多关联练习

1.保存课程

这里写图片描述
junit测试结果:
这里写图片描述

这里写图片描述
这里写图片描述

2.保存学生

这里写图片描述
junit测试结果:
这里写图片描述
这里写图片描述

3.保存课程同时保存学生

这里写图片描述
junit测试结果:
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述
原因解释:
这里是用Course建立学生和课程的关系,但是Course.hbm.xml的 inverse=”true” 不维护关系。

4.保存课程同时保存学生,并且建立关系

这里写图片描述

junit测试结果:
这里写图片描述

这里写图片描述
这里写图片描述
这里写图片描述

5.已经存在一个课程,新建一个学生,并且建立该学生和该课程之间的关系

这里写图片描述
junit测试结果:
这里写图片描述

这里写图片描述

这里写图片描述
这里写图片描述

6.已经存在一个课程,新建一个学生,并且建立该学生和该课程之间的关系

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

7.已经存在一个学生,已经存在一个课程,解除该学生和原来一个课程之间的关系,建立该学生和新的一个课程之间的关系

先移除集合中的一个元素,再添加
这里写图片描述
这里写图片描述
junit测试结果:
这里写图片描述

这里写图片描述

直接修改集合中的元素
这里写图片描述
这里写图片描述
这里写图片描述

8.已经存在一个学生,已经存在多个课程,解除该学生和原来多个课程之间的关系,建立该学生和新的多个课程之间的关系

这里写图片描述

这里写图片描述
junit测试结果:
这里写图片描述

这里写图片描述

9.已经存在一个学生,解除该学生和该学生的所有的课程之间的关系

这里写图片描述
junit测试结果:
这里写图片描述

这里写图片描述

10.解除该课程和所有的学生之间的关系,再重新建立该课程和一些新的学员之间的关系

这里写图片描述
这里写图片描述

junit测试结果:
这里写图片描述
这里写图片描述

全部源码

package cn.itcast.hibernate0909.manytomany;

import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

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

/**
 * 1、保存课程
 * 2、保存学生
 * 3、保存课程的时候同时保存学生
 * 4、保存课程的时候同时保存学生,并且建立课程和学生之间的关系
 * 5、已经存在一个课程,新建一个学生,并且建立该学生和该课程之间的关系
 * 6、已经存在一个学生,新建一个课程,并且建立该学生和该课程之间的关系
 * 7、已经存在一个学生,已经存在一个班级,解除该学生和原来班级之间的关系,建立该学生和新班级之间的关系
 * 8、已经存在一个学生,解除该学生和该学生所在班级之间的关系
 * 9、解除该班级和所有的学生之间的关系,再重新建立该班级和一些新的学员之间的关系
 * 10、解除该班级和所有的学生之间的关系
 * 11、删除班级
 *      *
 *          *  解除该班级和所有的学生之间的关系
 *          *  删除该班级
 *      *   
 *          删除班级的同时删除学生
 * 12、删除学生
 *      同删除班级
 * @author Administrator
 *
 */
public class ManyToManyTest {
    private static SessionFactory sessionFactory = null;
    static{
        Configuration  configuration = new Configuration();
        configuration.configure("cn/itcast/hibernate0909/manytomany/hibernate.cfg.xml");
        sessionFactory = configuration.buildSessionFactory();
    }
    /**
     * 保存课程
     */
    @Test
    public void testSaveCourse(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Course course = new Course();
        course.setCname("java程序设计");
        course.setDescription("java好!");
        session.save(course);
        transaction.commit();
        session.close();
    }

    /**
     * 保存学生
     */
    @Test
    public void testSaveStudent(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("cccc");
        student.setDescription("认真学习java");
        session.save(student);
        transaction.commit();
        session.close();
    }

    /**
     * 保存课程同时保存学生
     *      Hibernate: select max(cid) from Course
            Hibernate: select max(sid) from Student
            Hibernate: insert into Course (cname, description, cid) values (?, ?, ?)
            Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
                往Course表和Student表中分别插入了一行数据,和关系表没有关系
                通过映射文件可以看出,Student维护关系,但是从代码中找不到维护关系的代码
     */
    @Test
    public void testSaveCourse_Cascade(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        /*
         * 新建一个课程
         */
        Course course = new Course();
        course.setCname("java基础");
        course.setDescription("学好基础很重要");
        /**
         * 新建一个学生
         */
        Student student = new Student();
        student.setSname("大神");
        student.setDescription("java高手");

        Set<Student> students = new HashSet<Student>();
        students.add(student);
        /**
         * 通过课程建立课程与学生之间的关系
         */
        course.setStudents(students);//因为课程是一个新的,所以根据没有学生
        session.save(course);
        transaction.commit();
        session.close();
    }

    /**
     * 保存课程同时保存学生,并且建立关系
     */
    @Test
    public void testSaveCourse_Cascade_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        /**
         * 新建课程
         */
        Course course = new Course();
        course.setCname("java高级");
        course.setDescription("专讲框架");
        Set<Course> courses = new HashSet<Course>();
        courses.add(course);
        /**
         * 新建学生
         */
        Student student = new Student();
        student.setSname("班长");
        student.setDescription("高手,元方,你怎么看?");
        /*
         * 通过学生建立学生和课程之间的关系
         */
        student.setCourse(courses);
        session.save(student);
        transaction.commit();
        session.close();
    }

    /**
     * 已经存在一个课程,新建一个学生,并且建立该学生和该课程之间的关系
     *      Hibernate: select course0_.cid as cid0_0_, course0_.cname as cname0_0_, course0_.description as descript3_0_0_ from Course course0_ where course0_.cid=?
            Hibernate: select max(sid) from Student
            Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
            Hibernate: insert into student_course (sid, cid) values (?, ?)
                    该sql语句是维护关系
     */
    @Test
    public void testSaveStudent_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        /**
         * 1、查找一个课程
         * 2、新建一个学生
         * 3、通过学生来维护该学生和课程之间的关系
         */
        //查找课程2
        Course course = (Course)session.get(Course.class, 2L);
        //新建一个学生
        Student student = new Student();
        student.setSname("小明同学");
        student.setDescription("java高手");
        //通过学生来维护该学生和课程之间的关系
        Set<Course> courses = new HashSet<Course>();
        courses.add(course);
        student.setCourse(courses);
        session.save(student);
        transaction.commit();
        session.close();
    }

    /**
     * 已经存在一个学生,新建一个课程,并且建立该学生和该课程之间的关系
     */
    @Test
    public void testSaveCourse_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        /**
         * 1、新建一个课程
         * 2、查找学生
         * 3、在学生原来的基础上新添加一门课程
         */
        //新建课程
        Course course = new Course();
        course.setCname("项目课");
        course.setDescription("主攻软件项目");
        //查找学生
        Student student = (Student)session.get(Student.class, 2L);
        Set<Course> courses = student.getCourse();//获取该学生现在所有的课程
        courses.add(course);
        transaction.commit();
        session.close();
    }





    /**
     * 已经存在一个学生,已经存在一个课程,解除该学生和原来一个课程之间的关系,建立该学生和新的一个课程之间的关系
     */
    @Test
    public void testRealse_Rebuild_R(){
        /*
         * 分析:
         *   *  从需求分析上看,这个例子就是关系的操作
         *   *  要查看谁来维护关系,通过映射文件可以看出,Student来维护关系
         *   *  步骤
         *       *  查询sid为4的学生
         *       *  得到该学生的所有的课程
         *       *  遍历课程
         *          有可能有两种操作:
         *             *  先移除集合中的一个元素,再添加
         *             *  直接修改集合中的元素
         *  多对多的关系的维护包括两个操作
         *     第三张表的增加、删除
         */
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        //得到sid为4的学生
        Student student = (Student)session.get(Student.class, 4L);
        //得到cid为1的课程
        Course course2 = (Course)session.get(Course.class, 1L);
        //得到该学生的所有的课程
        Set<Course> courses = student.getCourse();
        for(Course course:courses){
            if(course.getCid().longValue()==2){
                courses.remove(course);//先移除

                break;
            }
        }
//      List<Course> courseList = new ArrayList<Course>(courses);
//      for(int i=0;i<courseList.size();i++){
//          if(courseList.get(i).getCid().longValue()==2){
//              courseList.set(i, course2); 
//          }
//      }
//      Set<Course> courses2 = new HashSet<Course>(courseList);
//      student.setCourse(courses2);
        courses.add(course2);//增加
        transaction.commit();
        session.close();
    }

    /**
     * 已经存在一个学生,已经存在多个课程,解除该学生和原来多个课程之间的关系,建立该学生和新的多个课程之间的关系
     */
    @Test
    public void testRealse_Rebuild_R_Many(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = (Student)session.get(Student.class, 4L);
        Course course3 = (Course)session.get(Course.class, 3L);
        Course course4 = (Course)session.get(Course.class, 4L);
        Set<Course> courses = student.getCourse();
        List<Course> courseList = new ArrayList<Course>(courses);   
//      for(int i=0;i<courseList.size();i++){
//          if(courseList.get(i).getCid().longValue()==1||courseList.get(i).getCid().longValue()==2){
//              courseList.remove(i); 
//              i = i - 1;  //使用List的remove方法,注意:remove之后i的值变化了,需要将i的值减一
//          }
//      }
//      
        Iterator<Course> iterator = courseList.iterator();
        while(iterator.hasNext()){
            Course c = iterator.next();
            if(c.getCid().longValue()==1 || c.getCid().longValue()==2){
                iterator.remove();
            }
        }


        courses = new HashSet<Course>(courseList);
        courses.add(course3);
        courses.add(course4);
        student.setCourse(courses);
        transaction.commit();
        session.close();
    }

    /*
     * 已经存在一个学生,解除该学生和该学生的所有的课程之间的关系
     */
    @Test
    public void testRealse_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = (Student)session.get(Student.class, 4L);
        student.setCourse(null);//解除该学生和所有的课程之间的关系
        transaction.commit();
        session.close();
    }

    /**
     * 解除该课程和所有的学生之间的关系,再重新建立该课程和一些新的学员之间的关系
     *   说明:
     *     *  必须由学生来维护关系
     *     *  已经条件是课程
     *         cid-->course-->set<student>-->遍历每一个student
     *         -->从每一个student中得到所有的课程-->找到要移除的课程-->移除
     */
    @Test
    public void testRealse_R_C(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Course course = (Course)session.get(Course.class, 3L);
        Set<Student> students = course.getStudents();
        for(Student student:students){
            Set<Course> courses = student.getCourse();
            for(Course course2:courses){
                if(course2.getCid().longValue()==3){
                    courses.remove(course2);
                    break;
                }
            }
        }
        Student student1 = (Student)session.get(Student.class, 1L);
        Student student2 = (Student)session.get(Student.class, 2L);
        student1.getCourse().add(course);
        student2.getCourse().add(course);
        transaction.commit();
        session.close();
    }

    /**
     * 解除该课程和所有的学生之间的关系
     */





}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值