在网上看到一篇文章写得很好,直接拿过来看这个了:
下面是转自:http://www.blogjava.net/asktalk/archive/2006/01/18/28548.html的一篇文章
在Hibernate中有三种状态,对它的深入理解,才能更好的理解hibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的。对于理解hibernate,JVM和sql的关系有更好的理解。对于需要持久化的JAVA对象,在它的生命周期中有三种状态,而且互相转化。
1, 临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;
2, 持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;
3, 游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。
特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;
×√ |
临时状态 (Transient) |
持久化状态 (Persistent) |
游离状态 (Detached) |
是否处于Session缓存中 |
× |
√ |
× |
数据库中是否有对应记录 |
× |
√ |
√ |
状态转换图,结束官方的和转载作者的
游离对象和临时对象异同:
两者都不会被Session关联,对象属性和数据库可能不一致;
游离对象有持久化对象关闭Session而转化而来,在内存中还有对象所以此时就变成游离状态了;
Hibernate和SQL的关系:
在操作了hibernate的方法如save()等后,并没有直接生成sql语句,去操作数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库;
下面举例说明:
一,Session.save(user)运行机理。
1,把User对象加入缓存中,使它变成持久化对象;
2,选用映射文件指定的标识生成ID;
3,在Session清理缓存时候执行:在底层生成一个insert sql语句,把对象存入数据库;
注意:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改;
二,Session.delete(user)运行过程。
如果user是持久化对象,则执行删除操作,同样底层数据库的执行条件是:在Session清理缓存时候;
如果user是游离对象:
1,将user对象和Session关联,使之成为持久化对象;
2,然后按照user 是持久化对象的过程执行;
下面是孔浩老师讲课的代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 | package org.zttc.itat.test; import java.text.SimpleDateFormat; import org.hibernate.Session; import org.junit.Test; import org.zttc.itat.model.User; import org.zttc.itat.util.HibernateUtil; public class TestStatus { private static final SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd" ); @Test public void testTransient() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setBorn(sdf.parse( "1976-2-3" )); u.setUsername( "zxl" ); u.setNickname( "赵晓六" ); u.setPassword( "123" ); //以上u就是Transient(瞬时状态),表示没有被session管理并且数据库中没有 //执行save之后,被session所管理,而且,数据库中已经存在,此时就是Persistent状态 session.save(u); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testPersistent01() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setBorn(sdf.parse( "1976-2-3" )); u.setUsername( "zxq" ); u.setNickname( "赵晓七" ); u.setPassword( "123" ); //以上u就是Transient(瞬时状态),表示没有被session管理并且数据库中没有 //执行save之后,被session所管理,而且,数据库中已经存在,此时就是Persistent状态 session.save(u); //此时u是持久化状态,已经被session所管理,当在提交时,会把session中的对象和目前的对象进行比较 //如果两个对象中的值不一致就会继续发出相应的sql语句 u.setNickname( "赵晓其" ); //此时会发出2条sql,一条用户做插入,一条用来做更新 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testPersistent02() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setBorn(sdf.parse( "1976-2-3" )); u.setUsername( "zxq" ); u.setNickname( "赵晓八" ); u.setPassword( "123" ); session.save(u); u.setPassword( "222" ); //该条语句没有意义 session.save(u); u.setNickname( "赵晓吧" ); //没有意义 session.update(u); u.setBorn(sdf.parse( "1988-12-22" )); //没有意义 session.update(u); //持久化状态(缓存中),事务提交的时候,才执行语句 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testPersistent03() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setBorn(sdf.parse( "1976-2-3" )); u.setUsername( "zxq" ); u.setNickname( "赵晓九" ); u.setPassword( "123" ); session.save(u); /* * 以下三条语句没有任何意义 */ session.save(u); session.update(u); session.update(u); u.setUsername( "zxj" ); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testPersistent04() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); //此时u是Persistent User u = (User)session.load(User. class , 10 ); //由于u这个对象和session中的对象不一致,所以会发出sql完成更新 u.setUsername( "aaa" ); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testPersistent05() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); //此时u是Persistent User u = (User)session.load(User. class , 10 ); session.getTransaction().commit(); session.beginTransaction(); u.setUsername( "123" ); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testPersistent06() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); //此时u是Persistent User u = (User)session.load(User. class , 11 ); u.setUsername( "123" ); //清空session session.clear(); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testDetach01() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setId( 10 ); u.setNickname( "abc" ); //当执行save的时候总是会添加一条数据,此时id就会根据Hibernate所定义的规则来生成(10是无效的) session.save(u); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testDetach02() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setId( 10 ); //完成update之后也会变成持久化状态 session.update(u); u.setBorn(sdf.parse( "1998-12-22" )); u.setNickname( "aaa" ); u.setUsername( "111" ); //会发出一条sql session.update(u); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testDetach03() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setId( 10 ); //完成update之后也会变成持久化状态 session.update(u); u.setBorn(sdf.parse( "1998-12-22" )); u.setNickname( "aaa" ); u.setUsername( "111" ); //会抛出异常 u.setId( 333 ); //会发出一条sql session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testDetach04() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); u.setId( 10 ); //现在u就是transient对象 session.delete(u); //此时u已经是瞬时对象,不会被session和数据库所管理 u.setNickname( "abc" ); //只会发出一条delete语句 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testDetach05() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User(); // u.setNickname( "abc" ); //如果u是离线状态【数据库中有,有ID就认为是,但session缓存中没有】就执行update操作,如果是瞬时状态就执行Save操作 //但是注意:该方法并不常用 session.saveOrUpdate(u); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } @Test public void testDetach06() { Session session = null ; try { session = HibernateUtil.openSession(); session.beginTransaction(); //u1已经是持久化状态 User u1 = (User)session.load(User. class , 11 ); System.out.println(u1.getNickname()); //u2是离线状态 User u2 = new User(); u2.setId( 11 ); u2.setPassword( "12223" ); //此时u2将会变成持久化状态,在session的缓存中就存在了两份同样的对象,在session中不能存在两份拷贝,否则会抛出异常 // //merge方法会判断session中是否已经存在同一个对象,如果存在就将两个对象合并 session.merge(u2); //最佳实践:merge一般不用 session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session!= null ) session.getTransaction().rollback(); } finally { HibernateUtil.close(session); } } }
|