Hibernate对象生命周期
一、对象状态及生命周期
Hibernate中对象有三种状态:瞬时状态(Transient)、持久状态(Persistent)、游离状态(Detached)。
瞬时状态:刚刚使用new语句创建,还没有被持久化,不处于Session缓存中。处于临时状态的Java对象被称为临时对象。Session中没有,数据库中没有。
持久化状态:已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。Session中有,数据库中有。
游离状态:已经被持久化,但不处于Session的缓存中。处于游离状态的Java对象被称为游离对象。Session中没有,数据库中有。
二、对象转换相关方法
-
瞬时状态转为持久状态
-
使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态。
-
使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态。
-
-
持久状态转为瞬时状态
-
执行Session对象的delete()方法后,对象由原来的持久状态转变为瞬时状态,因为此时该对象没有与任何的数据库数据关联。
-
-
持久状态转为游离状态
-
执行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态。
-
-
游离状态转为持久状态
-
重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象相关联。
-
-
游离状态转为瞬时状态
-
执行Session对象的delete()方法,对象由游离状态转为瞬时状态。
-
处于瞬时状态或游离状态的对象不再被其他对象引用时,会被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没有,数据库有 } }
三、对象三种状态的比较
State | Session | DB | |
---|---|---|---|
Transient | Y | N | N |
Persistent | Y | Y | Y |
Detached | Y | N |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!