Hibernate对象生命周期

Hibernate对象生命周期

一、对象状态及生命周期

Hibernate中对象有三种状态:瞬时状态(Transient)、持久状态(Persistent)、游离状态(Detached)。

瞬时状态:刚刚使用new语句创建,还没有被持久化,不处于Session缓存中。处于临时状态的Java对象被称为临时对象。Session中没有,数据库中没有。

持久化状态:已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。Session中有,数据库中有。

游离状态:已经被持久化,但不处于Session的缓存中。处于游离状态的Java对象被称为游离对象。Session中没有,数据库中有。

二、对象转换相关方法

 

 

  1. 瞬时状态转为持久状态

    1. 使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态。

    2. 使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态。

  1. 持久状态转为瞬时状态

    1. 执行Session对象的delete()方法后,对象由原来的持久状态转变为瞬时状态,因为此时该对象没有与任何的数据库数据关联。

  2. 持久状态转为游离状态

    1. 执行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态。

  3. 游离状态转为持久状态

    1. 重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象相关联。

  4. 游离状态转为瞬时状态

    1. 执行Session对象的delete()方法,对象由游离状态转为瞬时状态。

    2. 处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机按照垃圾回收机制处理。

下面就用代码操作一下,操作之前先封装一个可重复调用的Util工具类。

HibernateUtil.java

复制代码

/**
* 工具类
*/
public class HibernateUtil {
    //使用ThreadLocal模式初始化Session
    private static ThreadLocal<Session> threadLocal = new ThreadLocal<>();
    private static StandardServiceRegistry registry;
    private static SessionFactory sessionFactory;
​
    //静态块初始化Session工厂
    static {
        //初始化注册服务对象
        registry = new StandardServiceRegistryBuilder()
                .configure() // 默认加载hibernate.cfg.xml配置文件,如果配置文件名称被修改,.configure("修改的名称")
                .build();
        //从元信息获取Session工厂
        sessionFactory = new MetadataSources(registry)
                .buildMetadata()
                .buildSessionFactory();
    }
​
    //获取Session的方法
    public static Session getSession(){
        //从线程中获取Session
        Session session = threadLocal.get();
        //判断Session是否存在
        if(session == null || !session.isOpen()){
            //不存在从工厂获取Session
            //工厂是否存在,不存在重新加载工厂
            if(null == sessionFactory)
                buildSessionFactory();
            //从工厂获取session
            session = (null != sessionFactory) ? sessionFactory.openSession() : null;
            //放入线程
            threadLocal.set(session);
        }
        return session;
    }
​
    //加载session工厂
    private static void buildSessionFactory(){
        //初始化注册服务对象
        registry = new StandardServiceRegistryBuilder()
                .configure() // 默认加载hibernate.cfg.xml配置文件,如果配置文件名称被修改,.configure("修改的名称")
                .build();
        //从元信息获取Session工厂
        sessionFactory = new MetadataSources(registry)
                .buildMetadata()
                .buildSessionFactory();
    }
​
    //关闭session
    public static void closeSession(){
        Session session = threadLocal.get();
        threadLocal.set(null);
        if(null != session && session.isOpen())
            session.close();
    }
​
}
复制代码

 

 

三种状态测试类

复制代码
/**
 * new -> save -> close -> update
 */
  @Test
    public void test01(){
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
​
            user = new User();//瞬时状态,内存有,session没有,数据库没有
            user.setName("lisi");
            user.setPwd("123");
​
            session.save(user);//持久状态,内存有,session有,数据库有
​
​
            tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }finally {
            HibernateUtil.closeSession();//游离状态,内存有,session没有,数据库有
        }
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
​
            //这里只是为了学习,实际开发中不规范
            user.setName("赵六");//持续状态,内存有,session有,数据库有
            session.update(user);
​
            tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }finally {
            HibernateUtil.closeSession();//游离状态,内存有,session没有,数据库有
        }
    }
复制代码

 

get/load测试类

复制代码
   /**
     * get/load -> clear/evict
     */
    @Test
    public void test02() {
        Session session = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
​
            //get/load请求获得的对象持久状态,内存有,session有,数据库有
            //get请求是立即加载的过程,先查询缓存,缓存没有查询数据库
            user = session.get(User.class,1);
            //load请求懒加载的过程,如果使用到该对象才会去进行查询,先查询缓存,缓存没有查询数据库
            user = session.load(User.class,1);
            System.out.println(user);
​
            //清除缓存
            session.clear();//游离状态,内存有,session没有,数据库有
            session.evict(user);//清除某个缓存
​
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            HibernateUtil.closeSession();//游离状态,内存有,session没有,数据库有
        }
    }
复制代码

 

update测试类

复制代码
   /**
     * update
     */
    @Test
    public void testUpdate() {
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
​
            //违规操作
//            user = new User();
//            user.setId(6);
//            user.setName("刘德华");
            //先查询再修改
            user = session.get(User.class,1);
            if(null != user){
                user.setName("张学友");
                session.update(user);
            }
​
            session.update(user); //持久状态
​
            tx.commit();
​
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }finally {
            HibernateUtil.closeSession();//游离状态,内存有,session没有,数据库有
        }
    }
复制代码

 

delete测试类

复制代码
   /**
     * delete
     */
    @Test
    public void testDelete() {
        Session session = null;
        Transaction tx = null;
        User user = null;
        try {
            session = HibernateUtil.getSession();
            tx = session.beginTransaction();
​
            //违规操作
//            user = new User();
//            user.setId(6);
            //先查询再删除
            user = session.get(User.class,1);
            if(null != user){
                session.delete(user);//瞬时状态,内存有,session没有,数据库没有
            }
​
            tx.commit();
​
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }finally {
            HibernateUtil.closeSession();//游离状态,内存有,session没有,数据库有
        }
    }
复制代码

 

三、对象三种状态的比较

StateMemSessionDB
Transient Y N N
Persistent Y Y Y
Detached Y N Y
posted @   Resign~as  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示