您的位置:首页 > 其它

【Hibernate系列】(三):三种状态之原来我不懂你

2016-01-27 18:30 453 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[+]

前言

  在没有系统学习Hibernate之前,并不知道在使用Hibernate之后,持久化对象会被区分为三种状态。我的“无知”导致了其实我并怎么会用Hibernate,也就不能在项目中“知人善用”。就像是当对象处于Persistent状态,修改他的属性时,将来调用Session.commit时,就会同步到数据库。修改完属性再调用update(),其实就是多此一举。下面我们就来看看这三种状态是怎么定义的,在代码中是如何区分的。

持久化对象

  我们现在明确一下什么叫持久化对象,毕竟三种状态是用来区别持久化对象的。 

  【持久化对象】:指那些要存到数据库或硬盘中的内存中的对象。如:要转化成数据库中的记录的一些实体对象。

三种状态:

【Transient】(临时):对象没持久化到数据库中,也没被纳入到Session管理。

【Persistent】(持久):纳入到Session管理。

【Detached】(脱离):对象已经持久化到数据库中,但是没有被纳入Session管理。

说明: 

  有没有持久化到数据库很好理,就是该对象已经转化成了数据库表中的记录。 

  那什么叫做被纳入到Session管理呢?其实就是有没有被Session引用,我们知道Java的垃圾回收机制是,当一个内存中的对象没有其他引用它时,这样的对象就会在垃圾回收时,被视为垃圾,会从内存中清除。


如何确定是否被Session引用?

  调用session.save(对象);session.update(对象)的对象,或是通过session.load()返回的对象,都是被Session引用的,都是持久化状态的对象。

看看代码就知道

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">testSave1</span>() {
Session session = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
Transaction tx = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
User user = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
session = HibernateUtils.getSession();
tx = session.beginTransaction();

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Transient状态</span>
user = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> User();
user.setName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"zhangsan"</span>);
user.setPassword(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>);
user.setCreateTime(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Date());
user.setExpireTime(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Date());

session.save(user);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//id在sava完之后产生</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//调用了save之后,user对象转变为Persistent状态</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Persistent状态的对象:当对象的属性发生改变的时候</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//hibernate在清理缓存(脏数据检查)的时候,会和数据库同步</span>
user.setName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"lisi"</span>);

tx.commit();
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//commit之后产生两条语句</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Hibernate: insert into User (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Hibernate: update User set name=?, password=?, createTime=?, expireTime=? where id=?</span>
user.setName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wangwu"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//仍是持久化状态的对象,但是还没有同步到数据库中</span>
tx = session.beginTransaction();
tx.commit();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//抛异常:org.hibernate.TransactionException: Transaction not successfully started</span>

}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span>(Exception e) {
e.printStackTrace();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (tx != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
tx.rollback();
}
}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {
HibernateUtils.closeSession(session);
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//detached状态        </span>
user.setName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"王五"</span>);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
session = HibernateUtils.getSession();
session.beginTransaction();
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将detached状态的对象重新纳入session管理</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//此时将变为persistent状态的对象</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//persistent状态的对象,在清理缓存是会和数据库同步</span>
session.update(user);
session.getTransaction().commit();
}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span>(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {
HibernateUtils.closeSession(session);
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li></ul>


解释: 

  调用commit之后,对象被同步到数据库中。在commit之后,close之前,对象还是持久化状态,只是要再次同步到数据库,必须再调用commit方法,但是直接写这一句会抛异常,需要同时先开启事务,再commit才行。 

  此外:Persistent对象还可以通过get或load方法获得

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background: transparent;">public void testGet2() {
Session session = null<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
try {
session = HibernateUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSession</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.beginTransaction</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
//get方法加载数据,如果不存在返回null
User user = (User)session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.get</span>(User<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.class</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"54434343434343"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(user<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getTransaction</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.commit</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}catch(Exception e) {
e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getTransaction</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.rollback</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}finally {
HibernateUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.closeSession</span>(session)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
}

public void testLoad1() {
Session session = null<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
try {
session = HibernateUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getSession</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.beginTransaction</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;         </span>
User user = (User)session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.load</span>(User<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.class</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"4028808125534a540125534b952e0001"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
System<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.out</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.println</span>(user<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getName</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
user<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.setName</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"王五"</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getTransaction</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.commit</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}catch(Exception e) {
e<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.printStackTrace</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
session<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getTransaction</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.rollback</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}finally {
HibernateUtils<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.closeSession</span>(session)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li></ul>

总结

【1】.明确三种状态之间的区别:是否在数据库,是否在Session中 

【2】.三种状态之间的转化:

  


【3】.在调用commit之后,对持久化对象做的任何修改就都同步到数据库了,所以必须要懂Hibernate哦,要不然,“轻轻一碰”对象,他就“冬眠”在数据库楼!

转载博客:http://blog.csdn.net/u010924834/article/details/50570969
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hibernate