博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate学习(4)- Hibernate对象的生命周期
阅读量:6969 次
发布时间:2019-06-27

本文共 6178 字,大约阅读时间需要 20 分钟。

1、Hibernate对象的生命周期(瞬时状态、持久化状态、游离状态)

1、瞬时状态(Transient):

  使用new操作符初始化的对象就是瞬时状态,没有跟任何数据库数据相关联;
2、持久化状态(Parsistent):
  如果对象与Session对象关联起来,且该对象对应到数据库记录,则称该对象处于持久化状态。
3、游离状态(Detached)
  Session被关闭或调用了Session的evict或clear方法把它从Session中移除了,则该对象脱离了Session的管理,持久化状态变成游离状态,这表示该对象不在和数据库保持同步,不受hibernate管理。

2、三种状态的比较

Transient:瞬时状态的对象只存在于内存中。

Parsistent:持久状态的对象分别存在于内存、session对象、数据库之中。
Detached:游离状态的对象存在于内存、数据库之中,但不在session对象中。

3、三种状态之间的转换

1、转化路径详解

1)瞬时对象(Transient)

  new 创建 (无->Transient) ,即:对象通过构造方法成为瞬时态;

2)持久对象(Persistent)

  1.1)get/load (无->Persistent),即:对象可以由session的load或get方法直接成为持久态;

    get通过类名和id从数据库读取指定记录,无匹配记录返回null。

    load通过类名和id从数据库读取指定记录,无匹配记录抛ObjectNotException异常。

  1.2)save/saveOrUpdate/persist (Transient->Persistent) ,即:瞬时态对象可以通过save,saveOrUpdate或persist方法成为持久态;

  1.3)update/saveOrUpdate(Detached->Persistent),即:游离态对象则可以通过update,saveOrUpdate成为持久态;

3)游离对象(Detached)

  游离态只能由持久态转换而来(Persistent->Detached),通过close、clear、evict方法实现。

  evict--把某个对象从session中移除,变为游离态;

  clear--把所有对象从session中移除,对象全部变为游离态;
  close--关闭session,其中的对象全部变为游离态;

2、几种方法的详解

1、get 与 load

  都是从数据库中加载数据封装为java对象,直接变为持久态;

2、save,update与saveOrUpdate

  save是将瞬时态转为持久态;

  update是将游离态转为持久态;
  saveOrUpdate可以说是两者的综合,它执行时先判断对象的状态(主要是通过有无主键判断的),若是自由态,则save,若是游离态,则update;

3、save与persist

  两者都是将对象由瞬时态转为持久态,但返回值不同:save返回主键值,而persist不返回;

 4、实例,详见注解状态(封装的工具类详见Demo)

package com.demo.test;import org.hibernate.Session;import org.junit.Test;import com.demo.Utils.HibernateUtil;import com.demo.pojo.User;public class SessionTest {    @Test    public void saveTest() {        Session session = null;        User user = null;        try {            session = HibernateUtil.currentSession();            session.beginTransaction();            //创建瞬时状态对象            user = new User();            user.setName("东方不败");            user.setPwd("123456");            //user仍是一个瞬态对象                        //持久状态,user被session管理,并且id有值   -- oid            //此时user已变成 持久态对象            session.save(user);                        //在持久状态下脏数据检查:当提交事务,清理缓存时发现session中的数据与数据库的数据不一致时,会把session的数据更新到数据库            //保存以后,再修改对象,会产生多条sql语句,效率降低,所以在save前修改数据            user.setName("西方求败");            session.getTransaction().commit();                }catch (Exception e) {            e.printStackTrace();        }finally {            HibernateUtil.closeSession();        }        //close、clear、evict方法都会使持久态对象  变成 游离状态 -- user        user.setName("令狐冲");        try {            session = HibernateUtil.currentSession();            session.beginTransaction();            //update使对象变成 持久状态            session.update(user);            session.getTransaction().commit();                }catch (Exception e) {            e.printStackTrace();        }finally {            HibernateUtil.closeSession();        }    }        @Test    public void getTest() {        Session session = null;        try {            session = HibernateUtil.currentSession();            //get后变为持久状态            //get方法会立即查询该对象:范围(查询不到去下一级查询)从session -> sessionFactory ->数据库            //get方法找不到对象,不会有异常,返回nul            User user = session.get(User.class, 7L);            System.out.println(user.toString());                        User user2 = session.get(User.class, 17L);            System.out.println(user2);        }catch (Exception e) {            e.printStackTrace();        }finally {            HibernateUtil.closeSession();        }    }        @Test    public void loadTest() {        Session session = null;        try {            session = HibernateUtil.currentSession();            //load后变为持久状态(这里加载机制与get不同,稍后我会单独写一篇文章 介绍 get与load 的区别)            //对象不存在时,抛出异常            User user = session.load(User.class, 7L);            System.out.println(user.toString());                        User user2 = session.load(User.class, 17L);            System.out.println(user2.toString());        }catch (Exception e) {            e.printStackTrace();        }finally {            HibernateUtil.closeSession();        }    }        @Test    public void clearTest() {        Session session = null;        User user = null;        try {            session = HibernateUtil.currentSession();            session.beginTransaction();            user = session.get(User.class,7L);            System.out.println(user.getName());            session.getTransaction().commit();                session.clear();            //游离状态,不被session管理,数据库不会被更改            user.setName("任我行");            System.out.println(user.getName());        }catch (Exception e) {            e.printStackTrace();        }finally {            HibernateUtil.closeSession();        }    }        @Test    public void updateTest() {        Session session = null;        User user = null;        try {            session = HibernateUtil.currentSession();            session.beginTransaction();            //瞬时状态            //手动构造对象 也可以修改,但是需要指定所有的属性值,否则,不设置的对象会置空,不建议这样update数据            /*user = new User();            user.setId(7L);            user.setName("盈盈");            session.update(user);*/            //一般这样修改            //先去查询            user = session.get(User.class,7L);            if(user != null) {                user.setName("盈盈");                session.update(user);            }            session.getTransaction().commit();            }catch (Exception e) {            e.printStackTrace();        }finally {            HibernateUtil.closeSession();        }    }        @Test    public void deleteTest() {        Session session = null;        User user = null;        try {            session = HibernateUtil.currentSession();            session.beginTransaction();            //瞬时状态            //手动构造一个对象,指定主键是可以删除数据的,不建议这样搞            /*user = new User();            user.setId(7L);            session.delete(user);*/            //应该这样删除数据            //从数据先加载该对象,然后删除,可以避免异常            user = session.get(User.class, 7L);            if(user != null) {                session.delete(user);            }            session.getTransaction().commit();            }catch (Exception e) {            e.printStackTrace();        }finally {            HibernateUtil.closeSession();        }    }        }

 

 

PS:源码地址   

 

PS:原文地址  

 

转载于:https://www.cnblogs.com/JsonShare/p/8686078.html

你可能感兴趣的文章
Verilog语法
查看>>
Atom替换换行符
查看>>
Linux SendMail发送邮件失败诊断案例(四)
查看>>
SpringMVC+hibernate4事务处理
查看>>
大型网站架构演化历程
查看>>
[osg][原]自定义osgGA漫游器
查看>>
JSX 语法
查看>>
Day8 Servlet
查看>>
iOS 集成Protobuf,转换proto文件
查看>>
ZooKeeper伪集群环境搭建
查看>>
[Chromium]怎样安全的使用PostTask
查看>>
python 合并字典,相同 key 的 value 如何相加?
查看>>
Android开发之深入理解Android Studio构建文件build.gradle配置
查看>>
Martini源码剖析
查看>>
【spring boot】【log4jdbc】使用log4jdbc打印mybatis的sql和Jpa的sql语句运行情况
查看>>
BZOJ3265: 志愿者招募加强版(线性规划)
查看>>
Java提高:采用异常链传递异常
查看>>
SQL Server中LIKE %search_string% 走索引查找(Index Seek)浅析
查看>>
在WPF中制作正圆形公章
查看>>
dataframe 合并(append, merge, concat)
查看>>