Hibernate 一对多单向关联

本文详细介绍了一对多单向持久化的实现过程,包括持久化类的创建、映射文件的配置以及通过JUnit测试验证不同场景下的数据操作。

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

1.创建持久化类

1.创建Classes类

package cn.itcast.hibernate0909.onetomany.single;

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

public class Classes implements Serializable{
    private Long cid;
    private String cname;
    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;
    }

    private String description;

    private Set<Student> students;
}

2.创建Student类

package cn.itcast.hibernate0909.onetomany.single;

import java.io.Serializable;

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

    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;
    }
    private String description;
}

这里写图片描述

2.配置映射文件

1.配置Classes.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.onetomany.single.Classes"> 
        <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="20"></property>
        <property name="description" type="java.lang.String" length="100"></property>
        <!-- 
            set元素和类中的set集合对应
              *  从外键的角度建立classes与student之间的关系
              *  从类与类的角度建立classes与student之间的关系
            cascade级联
            inverse是用来维护关系的
                *  要么是一对多的关系
                *  要么多对多的关系
                *  谁来维护关系
                   inverse所在的映射文件对应的持久化对象维护关系
                默认值是false  表明维护关系
                   true  表明不维护关系
         -->
        <set name="students" cascade="save-update">
            <!-- 
                key是用来描述外键
                 column就代表外键的名字
             -->
             <key>
                <column name="cid"></column>
             </key>
             <!-- 
                classes和哪个对象进行关联
              -->
             <one-to-many class="cn.itcast.hibernate0909.onetomany.single.Student"/>
        </set>
    </class>
</hibernate-mapping>

这里写图片描述

2.配置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.onetomany.single.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="20"></property>
        <property name="description" type="java.lang.String" length="100"></property>
    </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/onetomany/single/Classes.hbm.xml" />
    <mapping
        resource="cn/itcast/hibernate0909/onetomany/single/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>

这里写图片描述

一对多单向关联练习

1.保存班级练习

这里写图片描述

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

2.保存学生练习

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

这里写图片描述
说明:这个操作只能插入一student对象,但是在student表中,外键任然为null

3.保存班级的时候同时保存学生

这里写图片描述

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

这里写图片描述

这里写图片描述

4. 在保存班级的同时,级联保存学生

这里写图片描述

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

这里写图片描述

这里写图片描述

5.保存班级的时候同时保存学生,并且建立班级和学生之间的关系

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

这里写图片描述

这里写图片描述

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

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

这里写图片描述

这里写图片描述

7.已经存在一个学生,新建一个班级,并且建立该学生和该班级之间的关系

这里写图片描述

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

这里写图片描述

这里写图片描述

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

这里写图片描述

这里写图片描述

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

这里写图片描述

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

这里写图片描述

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

这里写图片描述

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

修改数据库表之前的数据:
这里写图片描述

这里写图片描述

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

这里写图片描述

11.解除该班级和所有的学生之间的关系

这里写图片描述

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

这里写图片描述

12. 删除班级

修改数据库表之前的数据:
这里写图片描述

这里写图片描述

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

这里写图片描述

这里写图片描述

13.删除班级,同时删除学生

修改映射文件:
这里写图片描述
修改数据库表之前的数据:
这里写图片描述

这里写图片描述

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

这里写图片描述

这里写图片描述

全部源码

package cn.itcast.hibernate0909.onetomany.single;

import java.util.HashSet;
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 OneToManyTest {

    private static SessionFactory sessionFactory;

    static{
        Configuration  configuration = new Configuration();
        configuration.configure("cn/itcast/hibernate0909/onetomany/single/hibernate.cfg.xml");
        sessionFactory = configuration.buildSessionFactory();
    }


    /**
     * 1、保存班级
     */
    @Test
    public void testSaveClasses(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = new Classes();
        classes.setCname("0909java极品就业班");
        classes.setDescription("java学得就是好");
        session.save(classes);
        transaction.commit();
        session.close();
    }

    /**
     * 2、保存学生
     * 
     * 这个操作只能插入一student对象,但是在student表中,外键任然为null
     */
    @Test
    public void testSaveStudent(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("班长");
        student.setDescription("有班秘");
        session.save(student);
        transaction.commit();
        session.close();
    }


    /**
     * 保存班级的时候同时保存学生
     */
    @Test
    public void testSaveClassAndStudent(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("班秘");
        student.setDescription("男女不限,女士优先");
        session.save(student);

        Classes classes = new Classes();
        classes.setCname("0909java精品班");
        classes.setDescription("还是极品好");
        session.save(classes);
        transaction.commit();
        session.close();
    }


    /**
     * 在保存班级的同时,级联保存学生
     *      Hibernate: select max(cid) from Classes
            Hibernate: select max(sid) from Student
            Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
            Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
            Hibernate: update Student set cid=? where sid=?
     */
    @Test
    public void testSaveClass_Cascade_Student(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("菜肉");
        student.setDescription("男士");


        Set<Student> students = new HashSet<Student>();

        students.add(student);

        Classes classes = new Classes();
        classes.setCname("极品班级");
        classes.setDescription("还是极品好");

        classes.setStudents(students);
        session.save(classes);

        transaction.commit();
        session.close();
    }



    /**
     * 保存班级的时候同时保存学生,并且建立班级和学生之间的关系
     *      在classes.hbm.xml文件中
     *         <set name="students" cascade="save-update">
     *        inverse的值为默认或者false,才能让classes维护student的关系
     */
    @Test
    public void testSaveClassesAndStudent_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("某同学");
        student.setDescription("高富帅");


        Set<Student> students = new HashSet<Student>();

        students.add(student);

        Classes classes = new Classes();
        classes.setCname("重点班");
        classes.setDescription("还是重点好");

        classes.setStudents(students);
        session.save(classes);

        transaction.commit();
        session.close();
    }



    /**
     * 已经存在一个班级,新建一个学生,并且建立该学生和该班级之间的关系
     *      Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
            Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
                classes.getStudents()的时候发出的
            Hibernate: select max(sid) from Student
            Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
            Hibernate: update Student set cid=? where sid=?
                建立关系
     */
    @Test
    public void testSaveStudent_R(){
        /**
         * 1、查询班级
         * 2、新建学生
         * 3、建立关系
         */
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = new Student();
        student.setSname("小明同学");
        student.setDescription("昨天刚刚来");

        Classes classes = (Classes)session.get(Classes.class, 1L);
        //建立班级和学生之间的关系
        classes.getStudents().add(student);
        //classes.setStudents(students)  把班级中的学生重新更新了
        transaction.commit();
        session.close();
    }



    /**
     * 已经存在一个学生,新建一个班级,并且建立该学生和该班级之间的关系
     *      Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
            Hibernate: select max(cid) from Classes
            Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
            Hibernate: update Student set cid=? where sid=?
     */
    @Test
    public void testSaveClasses_R(){
        /**
         * 1、查找学生
         * 2、新建班级
         * 3、建立关系 
         */
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Student student = (Student)session.get(Student.class, 2L);
        Classes classes = new Classes();
        classes.setCname("科学班");
        classes.setDescription("很科学");
        Set<Student> students = new HashSet<Student>();
        students.add(student);
        classes.setStudents(students);
        session.save(classes);
        transaction.commit();
        session.close();
    }



    /**
     * 说明:   
     *     当Classes.hbm.xml映射文件中:
     *        <set name="students" cascade="save-update">
     *      当session.save/update classes时,隐式操作的对象是student,
     *      对student决定save操作还是update操作,主要的判断依据是student中sid值在数据库中有没有对应的值
     */

    /**
     * 已经存在一个学生,已经存在一个班级,解除该学生和原来班级之间的关系,建立该学生和新班级之间的关系
     *      Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
            Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
            Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
            Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
            Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
            Hibernate: update Student set cid=null where cid=?  解除关系
            Hibernate: update Student set cid=? where sid=?   建立关系
              只需要再重新建立关系即可
     */
    @Test
    public void testRealse_Rebuild(){
        /**
         * 1、查找班级
         * 2、查找学生
         * 3、解除关系
         * 4、建立关系
         */
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        //Classes classes = (Classes)session.get(Classes.class, 5L);
        Student student = (Student)session.get(Student.class, 4L);
        Classes classes2 = (Classes)session.get(Classes.class, 5L);
        //classes.getStudents().remove(student);//解除关系
        classes2.getStudents().add(student);//建立关系
        transaction.commit();
        session.close();
    }


    /**
     * 已经存在一个学生,解除该学生和该学生所在班级之间的关系
     *  Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
        Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
        Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
        Hibernate: update Student set cid=null where cid=?
           解除关系的语句
     */
    @Test
    public void testRealse_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        /**
         * 1、查询该学生
         * 2、查询该班级
         * 3、解除关系
         */
        Student student = (Student)session.get(Student.class, 5L);
        Classes classes = (Classes)session.get(Classes.class, 1L);
        classes.getStudents().remove(student);
        transaction.commit();
        session.close();
    }



    /**
     * 解除该班级和所有的学生之间的关系,再重新建立该班级和一些新的学员之间的关系
     */
    @Test
    public void testRealseAll_Rebuild_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes)session.get(Classes.class, 5L);
        List<Student> students = session.createQuery("from Student where sid in(3,4,5)").list();
        //重新建立班级和学生之间的关系
        classes.setStudents(new HashSet<Student>(students));
        transaction.commit();
        session.close();
    }



    /**
     * 解除该班级和所有的学生之间的关系
     */
    @Test
    public void testRealseAll_R(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes)session.get(Classes.class,5L);
        classes.setStudents(null);
        transaction.commit();
        session.close();
    }


    /**
     * 删除班级
     *   1、解除该班级和所有的学生之间的关系
     *       如果班级具体维护关系的能力,hibernate内部自动实现
     *   2、删除班级
     */
    @Test
    public void testDeleteClasses(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes)session.get(Classes.class, 1L);
        session.delete(classes);
        transaction.commit();
        session.close();
    }


    /**
     * 删除班级,同时删除学生
     *      Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
            Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
            Hibernate: update Student set cid=null where cid=?
                解除班级和学生之间的关系
            Hibernate: delete from Student where sid=?
            Hibernate: delete from Classes where cid=?
     */
    @Test
    public void testDeleteClasses_Cascade(){
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        Classes classes = (Classes)session.get(Classes.class, 5L);
        session.delete(classes);
        transaction.commit();
        session.close();
    }


    /**
     * 总结:
     *   1、在整个例子中,班级负责维护关系,只要班级维护关系就会发出update语句
     *   2、解除关系就是相对应的外键设置为null
     *   3、改变关系就是相对应的外键从一个值变成另外一个值
     *   4、在代码中的体现:
     *      classes.setStudents();  重新建立关系
     *      classes.getStudents().remove;  解除关系
     *      classes.setStudents(null); 解除所有的关系
     *      classes.getStudents().add() 在原有的关系的基础上再建立关系
     */

}

总结

1、在整个例子中,班级负责维护关系,只要班级维护关系就会发出update语句
2、解除关系就是相对应的外键设置为null
3、改变关系就是相对应的外键从一个值变成另外一个值
4、在代码中的体现:
classes.setStudents(); 重新建立关系
classes.getStudents().remove; 解除关系
classes.setStudents(null); 解除所有的关系
classes.getStudents().add() 在原有的关系的基础上再建立关系

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值