瞬时状态:transient, session没有缓存,数据库也没有记录,oid没有值。
通过new创建对象后,对象并没有立刻持久化,它并未与数据库中的数据有任何关联,此时Java对象的状态为瞬时状态。
Session对于瞬时状态的Java对象是一无所知的,当对象不再被其他对象引用时,它的所有数据也就丢失了,对象将会被Java虚拟机按照垃圾回收机制处理。
持久状态:persistent, session有缓存,数据库有记录,oid有值。
当对象与Session关联,被Session管理时,它就处于持久状态。处于持久状态的对象拥有数据库标识(数据库中的主键值)。
那么,对象是什么时候与Session发生关联的呢?有两种方法:
-
第一种,通过Sesison的查询接口,或者get()方法,或者load()方法从数据库中加载对象的时候,加载的对象是与数据库表中的一条记录关联的,此时对象与加载它的Session发生关联;
第二种,瞬时状态的对象,通过Session的save()方法或SaveOrUpdate()方法时,Java对象也与Session发生关联。
对于处于持久状态的对象,Session会持续跟踪和管理它们,如果对象的内部状态发生了任何变更,Hibernate会选择合适的时机(如事务提交时)将变更固化到数据库中。
脱管状态(游离态):detached,session没有缓存,数据库有记录,oid有值。
处于持久状态的对象,脱离与其关联的nSession的管理后,对象就处于游离状态。
处于游离状态的对象,Session无法保证对象所包含的数据与数据库中的记录一直,因为Hibernate已经无法感知对该对象的任何操作。
Session提供了两个方法(update()、merge()),将处于游离状态的对象,与一个新的Session发生关联。
此时,对象的状态就从游离状态重新转换为持久状态。
瞬时状态—session.save()—>持久状态
image.png
详细实例代码:
* import org.hibernate.Session;
* import org.junit.Test;
* import com.haidiyixiaoyu.domain.User;
* import com.haidiyixiaoyu.utils.HibernateUtils;
* //对象的三种状态
* public class Demo1 {
* @Test
* //演示三种状态
* public void fun1(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* User u = new User(); // 瞬时状态
* u.setName("tom"); // 瞬时状态
* u.setPassword("1234"); // 瞬时状态
* session.save(u); // 持久状态
* //问题: 调用完save方法,数据库中有没有对应记录?
* // 没有对应记录, 但是最终会被同步到数据库中.仍然是持久状态.
* //------------------------------------------------
* session.getTransaction().commit(); // 持久状态
* session.close(); // 游离状态
* }
* @Test
* //三种状态的转换
* // 瞬时 => 持久
* //瞬时:没有关联,没有id
* //持久: 有关联,有id
* public void fun2(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* User u = new User(); // 瞬时状态
* u.setName("tom"); // 瞬时状态
* u.setPassword("1234"); // 瞬时状态
* session.save(u); // 持久状态 save方法会使用主键生成策略,为User指定id. =>
* //主键自增 => 打印 insert语句
* //--------------------------// increment=> select max(id) ....
* //assigned => 需要手动指定主键,不指定将会报错
* session.getTransaction().commit(); // 持久状态
* //事务提交时,会把持久化状态对象同步到数据库中
* session.close(); // 游离状态
* }
* // 瞬时=> 游离
* // 瞬时: 没有关联,没有id
* // 游离: 没有关联,有id(与数据库中对应的id)
* @Test
* public void fun3(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* User u = new User(); // 瞬时状态
* u.setId(1); //游离
* //----------------------------------------------------
* session.getTransaction().commit(); // 持久状态
* //事务提交时,会把持久化状态对象同步到数据库中
* session.close(); // 游离状态
* }
* @Test
* // 持久=> 瞬时
* // 持久: 有关联,有id
* // 瞬时: 无关联,无id
* public void fun4(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* //通过get方法,得到持久状态对象
* User u= (User) session.get(User.class, 1); // 持久状态
* //----------------------------------------------------
* session.getTransaction().commit(); // 持久状态
* //事务提交时,会把持久化状态对象同步到数据库中
* session.close(); // 游离状态
* u.setId(null);//瞬时状态
* }
* @Test
* // 持久=> 瞬时
* // 持久: 有关联,有id
* // 瞬时: 无关联,无id
* public void fun5(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* //通过get方法,得到持久状态对象
* User u= (User) session.get(User.class, 1); // 持久状态
* session.evict(u);//将User对象与session的关联移除
* u.setId(null);//瞬时状态
* session.save(u);//持久状态
* //----------------------------------------------------
* session.getTransaction().commit(); // 持久状态
* //事务提交时,会把持久化状态对象同步到数据库中
* session.close(); // 游离状态
* }
* // 持久=> 游离
* @Test
* // 持久=> 游离
* //持久:有关联,有id
* //游离:没有关联,有id(与数据库中对应的id)
* // 只需要将session的关联取消
* public void fun6(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* //通过get方法,得到持久状态对象
* User u= (User) session.get(User.class, 1); // 持久状态
* session.evict(u);//游离
* //----------------------------------------------------
* session.getTransaction().commit(); // 游离状态
* session.close(); // 游离状态
* }
* @Test
* // 游离=> 瞬时
* //游离:没有关联,有id(与数据库中对应的id)
* //瞬时:无关联,无id
* // 移除ID
* public void fun7(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* //通过get方法,得到持久状态对象
* User u= (User) session.get(User.class, 1); // 持久状态
* session.evict(u);//游离
* u.setId(null);// 瞬时
* //----------------------------------------------------
* session.getTransaction().commit(); // 瞬时状态
* session.close(); // 瞬时状态
* }
* @Test
* // 游离=> 持久
* //游离:没有关联,有id(与数据库中对应的id)
* //持久:有关联,有id
* // 是否与Session关联
* public void fun8(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* //通过get方法,得到持久状态对象
* User u= (User) session.get(User.class, 1); // 持久状态
* session.evict(u);//游离
* session.update(u);//持久
* //----------------------------------------------------
* session.getTransaction().commit(); // 持久状态 -> 打印update语句
* session.close(); // 瞬时状态
* }
* //三种状态有什么用?
* // 持久状态,我们使用Hibernate主要是为了持久化我们的数据.
* // 对于对象的状态,我们期望我们需要同步到数据库的数据,都被转换成持久状态
* //持久化状态特点: Hibernate会自动将持久化状态对象的变化同步到数据库中.
* @Test
* public void fun9(){
* Session session = HibernateUtils.openSession();
* session.beginTransaction();
* //------------------------------------------------
* //通过get方法,得到持久状态对象
* User u= (User) session.get(User.class, 1); // 持久状态
* u.setName("jerry");//持久状态
* // u.setId(3);//与session建立关联的对象的ID,不允许修改.
* session.update(u);// 多余=> 因为Hibernate会自动将持久化状态对象的变化同步到数据库中.
* //----------------------------------------------------
* session.getTransaction().commit(); // 持久状态 -> 打印update语句
* session.close(); // 瞬时状态
* }
* }