📄 manipulatingdata.html
字号:
</p></li></ul></div></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="manipulatingdata-update-lock"></a>9.4.3. 把与Session脱离的对象重新绑定</h3></div></div><div></div></div><p> <tt class="literal">lock()</tt>方法是用来让应用程序把一个未修改的对象重新关联到新session的方法。 </p><pre class="programlisting">//just reassociate: 直接重新关联sess.lock(fritz, LockMode.NONE);//do a version check, then reassociate: 进行版本检查后关联sess.lock(izi, LockMode.READ);//do a version check, using SELECT ... FOR UPDATE, then reassociate: 使用SELECT ... FOR UPDATE进行版本检查后关联sess.lock(pk, LockMode.UPGRADE);</pre></div></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulatingdata-deleting"></a>9.5. 删除持久化对象</h2></div></div><div></div></div><p> 使用<tt class="literal">Session.delete()</tt>会把对象的状态从数据库中移除。当然,你的应用程序可能仍然持有一个指向它的引用。所以,最好这样理解:<tt class="literal">delete()</tt>的用途是把一个持久化实例变成临时实例。 </p><pre class="programlisting">sess.delete(cat);</pre><p> 你可以通过传递给<tt class="literal">delete()</tt>一个Hibernate 查询字符串来一次性删除很多对象。 </p><p> 你现在可以用你喜欢的任何顺序删除对象,不用担心外键约束冲突。当然,如果你搞错了顺序,还是有可能引发在外键字段定义的<tt class="literal">NOT NULL</tt>约束冲突。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulatingdata-flushing"></a>9.6. 同步(Flush)</h2></div></div><div></div></div><p> 每件隔一段时间,<tt class="literal">Session</tt>会执行一些必需的SQL语句来把内存中的对象和JDBC连接中的状态进行同步更新。这个过程被称为<span class="emphasis"><em>同步(flush)</em></span>,默认会在下面的时间点执行: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 在某些<tt class="literal">find()</tt>或者<tt class="literal">iterate()</tt>调用的时候 </p></li><li><p> 在<tt class="literal">net.sf.hibernate.Transaction.commit()</tt>的时候 </p></li><li><p> 在<tt class="literal">Session.flush()</tt>的时候 </p></li></ul></div><p> 涉及的SQL语句会按照下面的顺序安排: </p><div class="orderedlist"><ol type="1" compact><li><p> 所有对实体进行插入的语句,其顺序按照对象执行<tt class="literal">Session.save()</tt>的时间顺序 </p></li><li><p> 所有对实体进行更新的语句 </p></li><li><p> 所有进行集合删除的语句 </p></li><li><p> 所有对集合元素进行删除,更新或者插入的语句 </p></li><li><p> 所有进行集合插入的语句 </p></li><li><p> 所有对实体进行删除的语句,其顺序按照对象执行<tt class="literal">Session.delete()</tt>的时间顺序 </p></li></ol></div><p> (有一个例外时,如果对象使用<tt class="literal">native</tt>方式进行 ID 生成的话,它们一执行save就会被插入。) </p><p> 除非你明确地发出了<tt class="literal">flush()</tt>指令,关于Session<span class="emphasis"><em>合时</em></span>会执行这些JDBC调用是完全无法保证的,只能保证它们执行的前后顺序。当然,Hibernate保证,<tt class="literal">Session.find(..)</tt>绝对不会返回已经失效的数据,也不会返回错误数据。 </p><p> 也可以改变默认的设置,来让同步发生的不那么频繁。<tt class="literal">FlushMode</tt>类定义了三种不同的方式。大部分情况下,它们只由当你在处理“只读”的事务时才会使用,可能会得到一些(不是那么明显的)性能提高。 </p><pre class="programlisting">sess = sf.openSession();Transaction tx = sess.beginTransaction();sess.setFlushMode(FlushMode.COMMIT); //allow queries to return stale stateCat izi = (Cat) sess.load(Cat.class, id);izi.setName(iznizi);// execute some queries....sess.find("from Cat as cat left outer join cat.kittens kitten");//change to izi is not flushed!...tx.commit(); //flush occurs</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulatingdata-endingsession"></a>9.7. 结束一个Session</h2></div></div><div></div></div><p> 结束一个session包括四个独立的步骤: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 清洗session </p></li><li><p> 提交事务 </p></li><li><p> 关闭session </p></li><li><p> 处理异常 </p></li></ul></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="manipulatingdata-endingsession-flushing"></a>9.7.1. 同步(Flush) Session</h3></div></div><div></div></div><p> 如果你正在使用<tt class="literal">Transaction</tt>API,你就不用担心这个步骤。在事务提交的时候,隐含就会包括这一步。否则,你应该调用<tt class="literal">Session.flush()</tt>来确保你所有的修改都与数据库同步。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="manipulatingdata-endingsession-commit"></a>9.7.2. 提交数据库事务</h3></div></div><div></div></div><p> 如果你正在使用Hibernate 的<tt class="literal">Transaction</tt> API,代码类似这样: </p><pre class="programlisting">tx.commit(); // flush the Session and commit the transaction</pre><p> 如果你自行管理JDBC事务,你应该手工对JDBC 连接执行<tt class="literal">commit()</tt>。 </p><pre class="programlisting">sess.flush();sess.connection().commit(); // not necessary for JTA datasource</pre><p> 如果你决定<span class="emphasis"><em>不</em></span>提交你的更改: </p><pre class="programlisting">tx.rollback(); // rollback the transaction</pre><p> 或者: </p><pre class="programlisting">// not necessary for JTA datasource, important otherwisesess.connection().rollback();</pre><p> 如果你回滚了事务,你应该立即关闭和取消当前session,确保Hibernate内部状态的完整性。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="manipulatingdata-endingsession-close"></a>9.7.3. 关闭Session</h3></div></div><div></div></div><p> 调用<tt class="literal">Session.close()</tt>就标志这个session进入了尾声。<tt class="literal">close()</tt>主要的含义就是与这个session相关的JDBC连接会被放弃。 </p><pre class="programlisting">tx.commit();sess.close();</pre><pre class="programlisting">sess.flush();sess.connection().commit(); // not necessary for JTA datasourcesess.close();</pre><p> 如果你自行管理连接,<tt class="literal">close()</tt>会返回连接的一个引用,你就可以手工把它关闭,或者返回它到连接池去。其他情况下,<tt class="literal">close()</tt>会把它返回到连接池去。 </p></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="manipulatingdata-endingsession-exceptions"></a>9.7.4. 处理异常</h3></div></div><div></div></div><p> 如果<tt class="literal">Session</tt>抛出了一个exception(包括任何<tt class="literal">SQLException</tt>),你应该立刻回滚这个事务,调用<tt class="literal">Session.close)()</tt>来取消这个<tt class="literal">Session</tt>实例。<tt class="literal">Session</tt>中的一些特定方式会确保session<span class="emphasis"><em>不会</em></span>处于一个不稳定不完整的状态。 </p><p> 建议采用下面的异常处理片断: </p><pre class="programlisting">Session sess = factory.openSession();Transaction tx = null;try { tx = sess.beginTransaction(); // do some work ... tx.commit();}catch (Exception e) { if (tx!=null) tx.rollback(); throw e;}finally { sess.close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -