Hibernate入门六(单项的保存操作)

来源:互联网 发布:单片机方案开发 编辑:程序博客网 时间:2024/05/29 08:28
package com.itheima12.hibernate.onetomanysingle;import java.util.HashSet;import java.util.Set;import org.hibernate.Session;import org.hibernate.Transaction;import org.junit.Test;import com.itheima12.hibernate.domain.Classes;import com.itheima12.hibernate.domain.Student;import com.itheima12.hibernate.utils.HibernateUtils;/** * 一对多的单项 * @author zd *              一般操作                1、保存班级                2、保存学生                3、保存班级,保存学生                级联操作                4、保存班级级联保存学生                5、保存班级级联更新学生                6、更新班级级联保存学生                7、更新班级级联更新学生                8、删除班级级联删除学生                9、在班级有级联save-update的情况下,从关联得到学生,并且删除学生?                关系操作                8、已经存在一个班级,新建一个学生,把该学生加入到该班级(建立关系操作)                9、已经存在一个学生,新建一个班级,把该学生加入到该班级(建立关系操作)                10、已经存在一个学生,已经存在一个班级,把该学生加入到该班级                11、已经存在一个学生,把一个学生从一个班级转移到另外一个班级                在一的一方维护关系的时候,总会发出维护关系的update语句,该update语句就是更新外键                级联和关系的混合:                12、在删除班级的时候,解除班级和学生之间的关系 */public class OneToManySingleTest extends HibernateUtils{    @Test    //保存一个班级对象    public void testSaveClasses(){    //我继承自HibernateUtils 我就能直接调用getCurrentSession        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Classes classes = new Classes();        classes.setName("黑马JavaEE+hadoop的12期");        classes.setDescription("牛");        session.save(classes);        transaction.commit();    }    @Test    //保存一个学生对象    public void testSaveStudent(){    //我继承自HibernateUtils 我就能直接调用getCurrentSession        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Student student = new Student();        student.setName("班长");        student.setDescription("带头大哥");        session.save(student);        transaction.commit();    }    @Test    //想保存一个班级和学生    public void testSaveClassesAndSaveStudent(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Classes classes = new Classes();        classes.setName("黑马视频班");        classes.setDescription("野牛");        Student student = new Student();        student.setName("班秘");        student.setDescription("凤姐");        //保存两次        session.save(classes);        session.save(student);        transaction.commit();    }

这里写图片描述
这个运行起来 还是没有关联起来,而且一般不这么做,因为假设有100个学生对象的话,save100次。。。。
如果想要是进行级联操作的话,需要配置classess的配置文件

<?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"><hibernate-mapping>    <class name="com.itheima12.hibernate.domain.Classes">        <id name="cid" length="5">            <generator class="increment"></generator>        </id>        <property name="description" length="50"></property>        <property name="name" length="20"></property>        <!--             set元素针对的就是Classes类中的Set属性            cascade  级联操作               null  默认值               save-update                    在保存classes对象的时候,针对student进行保存或者更新的操作                    在更新classes对象的时候,针对student进行保存或者更新的操作               all               delete            inverse  关系操作               default:classes维护classes与student之间的关系               true:   classes不维护classes与student之间的关系               false:  classes维护classes与student之间的关系         -->        <set name="students" cascade="save-update" inverse="true">            <!--                 外键                    告诉hibernate,通过cid就可以建立classes与student之间的关联             -->            <key>                <column name="cid"></column>            </key>            <!--                 告诉hibernate,Classes类中的set集合中存放的是哪个元素             -->            <one-to-many class="com.itheima12.hibernate.domain.Student"/>        </set>    </class></hibernate-mapping>

配置好xml文件以后,继续编写测试类

    /**     * 在保存班级的时候,级联保存学生     */    @Test    public void testSaveClasses_Cascade_Save_Student(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Classes classes = new Classes();        classes.setName("黑马视频班");        classes.setDescription("野牛");        Student student = new Student();        student.setName("班秘");        student.setDescription("凤姐");        //建立classes与student之间的关联 但是如果在xml文件中没有配置 级联的话就会出现错误        //我先准备一个set集合         Set<Student> students = new HashSet<Student>();        students.add(student);        classes.setStudents(students);        session.save(classes); //显示保存的是classes,把保存student称为隐式保存        //这里有个很难排 transient 临时的         transaction.commit();    }    /**     * 在更新班级的时候,级联更新学生     * sessin.flush的时候     *    1、检查一级缓存中所有的持久化状态的对象     *        判断发出insert语句或者update语句     *    2、检查所有的持久化对象的关联对象     *         如果关联对象是由临时状态转化过来的,则对关联对象发出insert语句     *         如果关联对象是从数据库中提取出来的,则对照副本,决定是否发出update语句     */    @Test    public void testUpdateClasses_Cascade_Update_Student(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Classes classes = (Classes)session.get(Classes.class, 2L);//持久化类        Set<Student> students = classes.getStudents();//持久化类           for (Student student : students) {//把每一个student对象(关联对象)也放入到了一级缓存中            student.setDescription("bb");        }         students = classes.getStudents();//再次执行的话 发现并没有发出sql语句 说明          for (Student student : students) {//把每一个student对象(关联对象)也放入到了一级缓存中            student.setDescription("bb");        }        transaction.commit();    }

这里写图片描述

    /**     * 在更新班级的时候,添加学生     */    @Test    public void testUpdateClasses_Cascade_Save_Student(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        /*         * 给cid为2的班级添加一个学生         */         //首先我得得到cid为2的班级         Classes classes = (Classes)session.get(Classes.class, 2L);        //接下来我得整一个学生        Student student = new Student();        student.setName("美女1");        student.setDescription("小林志玲");        /**         * 建立班级与学生的关联         * Set<Student> students = new HashSet<Student>();         * students.add(student);         * 这个不行 会全覆盖 涉及到了关系操作         */        classes.getStudents().add(student);        transaction.commit();    }总结一下:在保存或者更新班级的时候,我操作学生    /**     * 在更新班级的时候,级联保存学生,并且维护关系     *  Hibernate:             select                classes0_.cid as cid0_0_,                classes0_.description as descript2_0_0_,                classes0_.name as name0_0_             from                Classes classes0_             where                classes0_.cid=?        Hibernate:             select                students0_.cid as cid0_1_,                students0_.sid as sid1_,                students0_.sid as sid1_0_,                students0_.description as descript2_1_0_,                students0_.name as name1_0_             from                Student students0_             where                students0_.cid=?        Hibernate:             select                max(sid)             from                Student        Hibernate:                    因为在Classes.hbm.xml文件中设置了级联                 <set name="students" cascade="save-update">            insert             into                Student                (description, name, sid)             values                (?, ?, ?)        Hibernate:                    因为在Classes.hbm.xml文件中,inverse没有写,默认classes维护classes与student之间的关系                   所以发出了更新关系的update语句 怎么体现维护关系 通过更新外键关系                   这个语句发出的关键是 inverse             update                Student             set                cid=?             where                sid=?     */    @Test    public void testUpdateClasses_Cascade_Save_Student_Inverse(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        /*         * 给cid为2的班级添加一个学生         */        Classes classes = (Classes)session.get(Classes.class, 2L);        Student student = new Student();        student.setName("美女1");        student.setDescription("小林志玲");        /**         * 建立班级与学生的关联         */        classes.getStudents().add(student);        transaction.commit();    }    /**     * 已经存在一个班级cid为1,已经存在一个学生,已经存在另外一个班级cid为2,该学生从cid为1的班级转到cid为2的班级     */    @Test    public void testTransform(){        /**         * 1、把cid为1,2和sid为1的对象提取出来         */        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        //Classes classes1 = (Classes)session.get(Classes.class, 1L);        Classes classes2 = (Classes)session.get(Classes.class, 2L);//发出查询的sql语句        Student student = (Student)session.get(Student.class, 1L);//发出查询的sql语句        //解除 classes1与student之间的关系        //classes1.getStudents().remove(student);        //建立classes2与student之间的关系        classes2.getStudents().add(student);        transaction.commit();    }    /**     * 解除该班级和该班级中的所有的学生之间的关系     */    @Test    public void testRealseR(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        /**         * 解除cid为2的班级和所有的学生之间的关系         */        Classes classes = (Classes)session.get(Classes.class,2L);        classes.setStudents(null);        transaction.commit();    }    /**     * 解除该班级和所有的学生之间的关系,再建立该班级和一些学生之间的关系     */    @Test    public void testRealseAllR_BuildSomeR(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        //解除cid为2的班级和所有的学生之间的关系        Classes classes = (Classes)session.get(Classes.class, 2L);        classes.setStudents(null);        Student student1 = new Student();        student1.setName("王二麻子");        Student student2 = new Student();        student2.setName("隔壁老李");        Set<Student> students = new HashSet<Student>();        students.add(student2);        students.add(student1);        classes.setStudents(students);        transaction.commit();    }    /**     * 删除一个班级     *   在删除班级之前,解除班级和学生之间的关系     *   Hibernate:             select                classes0_.cid as cid0_0_,                classes0_.description as descript2_0_0_,                classes0_.name as name0_0_             from                Classes classes0_             where                classes0_.cid=?        Hibernate:                    因为classes负责维护关系,所以该语句就是解除关系的sql语句            update                Student             set                cid=null             where                cid=?        Hibernate:             delete             from                Classes             where                cid=?     */    @Test    public void testDeleteClasses_1(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Classes classes = (Classes)session.get(Classes.class, 1L);        session.delete(classes);        transaction.commit();    }    /**     * 在 Classes.hbm.xml文件中     *     <set name="students" cascade="all">     *     在删除班级的时候,级联删除学生     */    @Test    public void testDeleteClasses_2(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Classes classes = (Classes)session.get(Classes.class, 1L);        session.delete(classes);        transaction.commit();    }    /**     * 删除一个学生,但是该学生必须从班级中提取出来     *   因为在Classes.hbm.xml文件中     *      <set name="students" cascade="save-update">     *      classes针对student是关联的     *      而程序中的student对象是从classes中提取出来的关联对象,所以不能删除     */    @Test    public void testError(){        Session session = sessionFactory.getCurrentSession();        Transaction transaction = session.beginTransaction();        Classes classes = (Classes)session.get(Classes.class, 1L);        Set<Student> students = classes.getStudents();        //classes.setStudents(null);//解除关系        for (Student student : students) {            session.delete(student);        }        transaction.commit();    }}

这里来解释一下:为什么每次执行都跟着一个update语句
这里写图片描述
我要建立联系班级和学生的联系,在hibernate面向对象操作,cascade是级联操作,hibernate当中有个属性叫做inverse
inverse 关系操作

  • default:classes维护classes与student之间的关系
  • true: classes不维护classes与student之间的关系
  • false: classes维护classes与student之间的关系
原创粉丝点击