Hibernate-ORM:06.Hibernate中三种状态

简介:   ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------       本篇博客主要叙述Hibernate中的三种状态:临时状态(瞬时状态),持久状态,游离状态 commit和flush三种状态间的使用,commit和flush的区别: save...

 

 

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------

 

 

 

本篇博客主要叙述Hibernate中的三种状态临时状态(瞬时状态),持久状态游离状态

commitflush三种状态间使用,commit和flush的区别

saveOrUpdatemerge三种状态间的使用saveOrUpdate和merge的区别

前方标注一下,用的是mysql数据库,主键生成策略是increment

 

一,Hibernate-ORM的对象的三种状态

  * Hibernate对象的三种状态
  * 1.临时状态(瞬时态)(临时态,自由态)
  * 我们通过new关键字创建出一个类的实例对象, 这个对象和hibernate没有任何关系
  * 2.持久状态
  * 对象被session管理。就会产生一个OID(主键标识符)这个对象和hibernate有关系
  * 3.游离状态(托管态)
  * 曾经被session管理过有OID

  *和瞬时态的区别在于,是否存在OID!

  大话一下:临时状态就是没有关系,就像你和大街上任意一个女孩没有关系,持久状态就是你和她有了联系(男女朋友,结婚),游离状态就是已经分手了(但是有过曾经)

 

二,一张图揭秘如何进入各个状态的方法

    

 

 

三,各个状态的小案例

 

    @Test
    /*简单写一下三种状态,和根据这个increment主键生成策咯生成记录
    *
    *
    ----------------------------------
    Hibernate: select max(tid) from Teacher
    ----------------------------------
    Hibernate: insert into Teacher (name, tid) values (?, ?)
    * */
    public void t01ThreeStatus01(){
        System.out.println("----------------------------------");
        Teacher teacher=new Teacher("孟六爱自由");//临时状态(瞬时状态)
        session.save(teacher);//持久状态
        System.out.println("----------------------------------");
        tr.commit();
        session.evict(teacher);//游离状态
    }

 

 

四,commit()和flush():

  1.区别

 

    * commit()和flush()的区别
    *
    * flush():是缓存清理,把缓存中的数据同步到数据库但是不会持久化
    * commit():在执行的时候,会默认执行flush(),之后会持久化
    * flush()在执行的时候会进行缓存清理,在缓存清理的时候会进行脏检查

  2. 什么是脏检查
    * 在一个对象被session管理的时候,会创建这个对象的快照,
    * 我们之后commit的时候,会拿当前的对象信息和之前对象的快照进行对比,
    * 如果当前对象的属性发生改变,那么现在的对象就是脏对象!
    * 脏对象会被同步到数据库中!

 

  3.对一个持久化状态的commit操作

 

    @Test
    /*
    * 写一下commit可以提交属于持久化状态的数据
    *
    Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
    Hibernate: update Teacher set name=? where tid=?
    * */
    public void t02CommitAndFlush01(){
        Teacher teacher=session.get(Teacher.class,3);/*持久化状态*/
        teacher.setName("CommitTest1");
        tr.commit();
    }

 

    它会在没有update()的情况下也会做修改,并且持久化到数据库

  4.对一个持久化状态的flush操作

 

    @Test
    /*
    * 写一下flush可以同步到数据库,但是不会持久化
    *
    Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
    *
    * */
    public void t02CommitAndFlush02(){
        Teacher teacher=session.get(Teacher.class,3);/*持久化状态*/
        teacher.setName("flushTest1");
        session.flush();
    }

 

    它可以同步到数据库,之后执行完毕之后就回滚掉了,不会持久化,我下面一个例子做证明

  5.证明flush只是做同步,不是持久化

 

    @Test
    /*
    * 测试flush是否真实同步到数据库,
    * 排除缓存,看看是否确实持久化到数据库中还是只是同步,一会就回滚
    *
    Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
    ============================CommitTest1
    Hibernate: update Teacher set name=? where tid=?
    Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
    ============================flushTest2
    * */
    public void t02CommitAndFlush03(){
        Teacher teacher=session.get(Teacher.class,3);/*持久化状态*/
        System.out.println("============================"+teacher.getName());/*CommitTest1*/
        teacher.setName("flushTest2");
        session.flush();    //清理缓存
        session.clear();    //清空缓存
        teacher=session.get(Teacher.class,3);/*持久化状态*/
        System.out.println("============================"+teacher.getName());/*flushTest2*/
    }

 

 

五,saveOrUpdate()和merge():

  1.区别

    最核心的区别:::::::merge()不会改变对象的状态!!!

    * save(): 把瞬时态转换成持久态
    * update(): 把游离态转换成持久态
    * saveOrUpdate():
    * 会根据对象是否有OID来判断执行save还是update
    * 如果有oid 执行update
    * 如果没有oid 执行save
    * merge(): 产生的sql语句和saveOrUpdate有点类似
    * 但是!!!!!
    * 01.merge不会改变对象的状态
    * 02.当我们的对象处于瞬时状态时,会将对象复制一份到session的缓存中,
    * 然后执行save方法,执行insert

 

  2.持久化状态下的saveOrUpdate():

 

    @Test
    /*
    * saveOrUpdate
    * 它会改变状态
    * 它会根据有没有oid标识(此java对象的状态),来选择执行save还是update
    *
    *  当是update的时候的案例
    *
    Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
    Hibernate: update Teacher set name=? where tid=?
    * */
    public void t03SaveOrUpdate01(){
        Teacher teacher=session.get(Teacher.class,4);/*持久化状态*/
        teacher.setName("SaveOrUpdate01");
        session.saveOrUpdate(teacher);  /*他走的是update*/
        tr.commit();
    }

 

  3.临时(瞬时)状态下的SaveOrUpdate():

 

    @Test
    /*
    * saveOrUpdate
    * 它会改变状态
    * 它会根据有没有oid标识(此java对象的状态),来选择执行save还是update
    *
    *  当是save的时候的案例
    *
    Hibernate: select max(tid) from Teacher
    Hibernate: insert into Teacher (name, tid) values (?, ?)
    *
    * */
    public void t03SaveOrUpdate02(){
        Teacher teacher=new Teacher("王老师66");//临时状态(瞬时状态)
        teacher.setName("SaveOrUpdate02");
        session.saveOrUpdate(teacher);  /*他走的是update*/
        tr.commit();
    }

 

  4.(临时)瞬时状态下的merge():

 

    @Test
    /*
    * Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
    * 案例一,save
    *
    Hibernate: select max(tid) from Teacher
    Hibernate: insert into Teacher (name, tid) values (?, ?)
    * */
    public void t04Merge01(){
        Teacher teacher=new Teacher("Merge01goodnice");//临时状态(瞬时状态)
        teacher.setName("Merge01");
        session.merge(teacher);  /*他走的是update*/
        tr.commit();
    }

 

  5.持久化状态下的merger():

 

    @Test
    /*
    * Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
    * 案例二,update
    *
    Hibernate: select teacher0_.tid as tid1_0_0_, teacher0_.name as name2_0_0_ from Teacher teacher0_ where teacher0_.tid=?
    Hibernate: update Teacher set name=? where tid=?
    * */
    public void t04Merge02(){
        Teacher teacher=session.get(Teacher.class,4);/*持久化状态*/
        teacher.setName("Merge02");
        session.merge(teacher);  /*他走的是update*/
        tr.commit();
    }

 

  6.测试merge()是否会改变对象状态(一):

    先准备一个临时对象,做merge操作,之后做update()操作,因为update得操作持久化对象,所以,只需要看报不报错就知道merge会不会改变状态

 

    @Test
    /*
    * Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
    * 案例三,他不会改变状态的案例
    它会抛异常,因为不是持久化状态的无法用update,虽然他已经进行了插入操作

    Hibernate: select max(tid) from Teacher
    Hibernate: insert into Teacher (name, tid) values (?, ?)

    org.hibernate.TransientObjectException: The given object has a null identifier: cn.dawn.day02.entity.Teacher
    ........
    * */
    public void t04Merge03(){
        Teacher teacher=new Teacher("Merge03");//临时状态(瞬时状态)
        session.merge(teacher);  /*他走的是save,但是没有改变为持久化状态*/
        tr.commit();
        session.update(teacher);
        tr.commit();
    }

 

    报错,所以merge()没有改变对象状态

  7.测试merge()是否会改变对象状态(二)

    准备一个临时状态的对象,执行俩次merge(),看是发俩条insert还是有update

 

    @Test
    /*
    * Merge和SaveOrUpdate用法类似,但是他不能改变状态,所以有些时候他会有点问题
    * 案例四,创建一个对象后,merge一次,之后改变他的属性,再marge一次。。。
    他会执行俩次save,因为此对象是临时状态,merge不会改变java对象的状态
    Hibernate: select max(tid) from Teacher
    Hibernate: insert into Teacher (name, tid) values (?, ?)
    Hibernate: insert into Teacher (name, tid) values (?, ?)
    ........
    * */
    public void t04Merge04(){
        Teacher teacher=new Teacher("Merge04");//临时状态(瞬时状态)
        session.merge(teacher);  /*他走的是save,但是没有改变为持久化状态*/
        teacher.setName("Merge04NewValue");
        session.merge(teacher);
        tr.commit();
    }

 

    结论:两条insert,所以merge()不会改变对象状态

 

 

 

作者:晨曦Dawn

转载请注明出处:博客地址https://www.cnblogs.com/DawnCHENXI/p/9101984.html

如果有错误,请指出!感激不尽!!!!!!!!!!!!!!!!!!!!!!!!!!!!

目录
相关文章
|
XML SQL Java
Hibernate-ORM:14.Hibernate中的命名查询
      ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------         本篇博客讲述命名查询,所谓命名查询是什么呢? Hibernate中允许我们在xml,实体类,甚至注解的方式来编写查询语句,本篇博客将讲述xml中的方式 一,准备好准备工作,我由于上篇博客把大量的准备都做好,所以,本篇从简 二,预览hbm.
1029 0
|
SQL Java 数据库连接
Hibernate-ORM:15.Hibernate中的Criteria查询
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------         本篇博客讲师Hibernate中的Criteria查询! 一,Criteria简介:   刚接触Hibernate的时候,就有一个概念,全自动的ORM框架,不用写...
980 0
|
SQL 缓存 Java
Hibernate-ORM:16.Hibernate中的二级缓存Ehcache的配置
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------         本篇博客讲述Hibernate中的二级缓存的配置,作者将使用的是ehcache缓存 一,目录   1.
1223 0
|
Java 关系型数据库 程序员
Hibernate-ORM:13.Hibernate中的连接查询
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------     本篇博客将会解释Hibernate中的连接查询(各种join) 一,目录   1.
903 0
|
Java 关系型数据库 数据库连接
Hibernate-ORM:12.Hibernate中的多对多关联关系
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------       本篇博客将讲述Hibernate中的多对多关联关系的操作,准备的篇幅较少,望海涵   一,讲述多对多   多对多的关联关系,比如学生和教师来说,一个学生由多个教师授课...
1244 0
|
安全
Hibernate-ORM:09.Hibernate中的getCurrentSession()
  ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------         本篇博客将讲述,以优雅的方式创建session对象,我将会说明优点,并提炼成工具类   优点:   1.
1257 0
|
Java 关系型数据库 MySQL
Hibernate-ORM:10.Hibernate中的分页
  ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------       本篇博客讲述Hibernate中的分页 hibernate中的分页其实很好写,它通过操作对象的方式,来进行分页查询操作 分页无非就是查俩个:1.
938 0
|
Java 关系型数据库 数据库连接
Hibernate-ORM:11.Hibernate中的关联查询
      ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------         本篇博客将讲述Hibernate中的关联查询,及其级联(cascade)操作,以及指定哪一方维护关联关系的(inverse)   一,讲述目录如下:   1.
1196 0
|
SQL Java 数据库连接
Hibernate-ORM:07.Hibernate中的参数绑定
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------     本篇博客会讲解Hibernate中的参数绑定,就是相当于sql语句中的where后面的条件   一,讲解概述:   1.
1039 0
|
SQL Java 数据库连接
Hibernate-ORM:08.Hibernate中的投影查询
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------       本篇博客将叙述hibernate中的投影查询 一,目录:   1.解释什么是投影查询   2.
1021 0