📄 manipulating-data.html
字号:
如果对象的标识值与<tt class="literal">unsaved-value</tt>中的条件匹配,调用<tt class="literal">save()</tt>来保存它 </p></li><li><p> 如果对象使用了版本(<tt class="literal">version</tt>或<tt class="literal">timestamp</tt>),那么除非设置<tt class="literal">unsaved-value="undefined"</tt>,版本检查会发生在标识符检查之前. </p></li><li><p> 如果这个session中有另外一个对象具有同样的标识符,抛出一个异常 </p></li></ul></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulating-data-s8b"></a>8.6. 把在先前的session中保存或装载的对象重新与新session建立关联(reassociate)</h2></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 class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulating-data-s9"></a>8.7. 删除持久化对象</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="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulating-data-s10"></a>8.8. 对象图(Graphs of objects)</h2></div></div><div></div></div><p> 要保存或者更新一个对象关联图中所有的所有对象,你必须做到: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 保证每一个对象都执行<tt class="literal">save()</tt>, <tt class="literal">saveOrUpdate()</tt> 或 <tt class="literal">update()</tt>方法,或者, </p></li><li><p> 在定义关联对象的映射时,使用<tt class="literal">cascade="all"</tt>或<tt class="literal">cascade="save-update"</tt>。 </p></li></ul></div><p> 类似的,要删除一个关系图中的所有对象,必须: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 对每一个对象都执行<tt class="literal">delete()</tt>,或者 </p></li><li><p> 在定义关联对象的映射时,使用<tt class="literal">cascade="all"</tt>,<tt class="literal">cascade="all-delete-orphan"</tt>或<tt class="literal">cascade="delete"</tt>。 </p></li></ul></div><p> 建议: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 如果子对象的生命期是绑定到父对象的生命期的,通过指定<tt class="literal">cascade="all"</tt>可以把它变成一个<span class="emphasis"><em>自动管理生命周期的对象(lifecycle object)</em></span>。 </p></li><li><p> 否则,必须在应用程序代码中明确地执行<tt class="literal">save()</tt>和<tt class="literal">delete()</tt>。如果你想少敲一些代码,可以使用<tt class="literal">cascade="sve-update"</tt>,然后只需明确地<tt class="literal">delete()</tt>。 </p></li></ul></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="manipulating-data-s11a"></a>8.8.1. 自动管理生命周期的对象(lifecycle object)</h3></div></div><div></div></div><p> 对一种关联(多对一,或者集合)使用<tt class="literal">cascade="all"</tt>映射,就把这种关联标记为一种<tt class="literal">父/子(parent/child)</tt>风格的关系,对父对象进行保存/更新/删除会导致对(所有)子对象的保存/更新/删除。但是这个比喻并不是特别确切。如果父对象解除了对某个子对象的关联,那这个子对象就<span class="emphasis"><em>不会</em></span>被自动删除了。除非这是一个<tt class="literal">一对多</tt>的关联,并且标明了<tt class="literal">cascade="all-delete-orphan"(所有-删除-孤儿)</tt>。级联操作的精确语义在下面列出: </p><div class="itemizedlist"><ul type="disc" compact><li><p> 如果父对象被保存,所有的子对象会被传递到<tt class="literal">saveOrUpdate()</tt>方法去执行 </p></li><li><p> 如果父对象被传递到<tt class="literal">update()</tt>或者<tt class="literal">saveOrUpdate()</tt>,所有的子对象会被传递到<tt class="literal">saveOrUpdate()</tt>方法去执行 </p></li><li><p> 如果一个临时的子对象被一个持久化的父对象引用了,它会被传递到<tt class="literal">saveOrUpdate()</tt>去执行 </p></li><li><p> 如果父对象被删除了,所有的子对象对被传递到<tt class="literal">delete()</tt>方法执行 </p></li><li><p> 如果临时的子对象不再被持久化的父对象引用,<tt class="literal">什么都不会发生</tt>(必要时,程序应该明确的删除这个子对象),除非声明了<tt class="literal">cascade="all-delete-orphan"</tt>,在这种情况下,成为“孤儿”的子对象会被删除。 </p></li></ul></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="manipulating-data-s11b"></a>8.8.2. 通过可触及性决定持久化(Persistence by Reachability)</h3></div></div><div></div></div><p> Hibernate还没有完全实现“通过可触及性决定持久化”,后者暗示会对垃圾收集进行(效率不高的)持久化。但是,因为很广泛的呼声,Hibernate实现了一种意见,如果一个实体被一个持久化的对象引用,它也会被持久化。注明了<tt class="literal">cascade="save-update"</tt>的关联就是按照这种思路运作的。如果你希望在你的整个程序中都贯彻这个方法,你可以在<tt class="literal"><hibernate-mapping></tt>元素的<tt class="literal">default-cascade</tt>属性中指定这种级联方式。 </p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulating-data-s12"></a>8.9. 清洗(Flushing) -- 这个词很难翻译,不能使用“刷新”,因为刷新一词已经被"refresh"使用了。有什么好的建议?</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="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="manipulating-data-s13"></a>8.10. 结束一个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>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -