📄 collections.html
字号:
</p><p> 关联还可以在运行时使用<tt class="literal">filter()</tt>根据任意的条件来排序。 </p><pre class="programlisting">sortedUsers = s.filter( group.getUsers(), "order by this.name" );</pre></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="collections-idbag"></a>6.7. <tt class="literal">使用<idbag></tt></h2></div></div><div></div></div><p> 如果你完全信奉我们对于“联合主键(composite keys)是个坏东西”,和“实体应该使用(无机的)自己生成的代用标识符(surrogate keys)”的观点,也许你会感到有一些奇怪,我们目前为止展示的多对多关联和值集合都是映射成为带有联合主键的表的!现在,这一点非常值得争辩;看上去一个单纯的关联表并不能从代用标识符中获得什么好处(虽然使用组合值的集合<span class="emphasis"><em>可能</em></span>会获得一点好处)。不过,Hibernate提供了一个(一点点试验性质的)功能,让你把多对多关联和值集合应得到一个使用代用标识符的表去。 </p><p> <tt class="literal"><idbag></tt> 属性让你使用bag语义来映射一个<tt class="literal">List</tt> (或<tt class="literal">Collection</tt>)。 </p><pre class="programlisting"><idbag name="lovers" table="LOVERS" lazy="true"> <collection-id column="ID" type="long"> <generator class="hilo"/> </collection-id> <key column="PERSON1"/> <many-to-many column="PERSON2" class="eg.Person" outer-join="true"/></idbag></pre><p> 你可以理解,<tt class="literal"><idbag></tt>人工的id生成器,就好像是实体类一样!集合的每一行都有一个不同的人造关键字。但是,Hibernate没有提供任何机制来让你取得某个特定行的人造关键字。 </p><p> 注意<tt class="literal"><idbag></tt>的更新性能要比普通的<tt class="literal"><bag></tt>高得多!Hibernate可以有效的定位到不同的行,分别进行更新或删除工作,就如同处理一个list, map或者set一样。 </p><p> 在目前的实现中,还不支持使用<tt class="literal">identity</tt>标识符生成器策略来生成<tt class="literal"><idbag></tt>集合的标识符。 </p></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="collections-bidirectional"></a>6.8. 双向关联(Bidirectional Associations)</h2></div></div><div></div></div><p> <span class="emphasis"><em>双向关联</em></span>允许通过关联的任一端访问另外一端。在Hibernate中, 支持两种类型的双向关联: </p><div class="variablelist"><dl><dt><span class="term">一对多(one-to-many)</span></dt><dd><p> Set或者bag值在一端, 单独值(非集合)在另外一端 </p></dd><dt><span class="term">多对多(many-to-many)</span></dt><dd><p> 两端都是set或bag值 </p></dd></dl></div><p> </p><p> 请注意Hibernate不支持带有索引的集合(list,map或者array)作为"多"的那一端的双向one-to-many关联,你必须使用集合或者bag映射. </p><p> 要建立一个双向的多对多关联,只需要映射两个many-to-many关联到同一个数据库表中,并再定义其中的一端为<span class="emphasis"><em>inverse</em></span>(使用哪一端要根据你的选择)。这里有一个从一个类关联到<span class="emphasis"><em>他自身</em></span>的many-to-many的双向关联的例子(每一个category都可以有很多items,每一个items可以属于很多categories): </p><pre class="programlisting"><class name="org.hibernate.auction.Category"> <id name="id" column="ID"/> ... <bag name="items" table="CATEGORY_ITEM" lazy="true"> <key column="CATEGORY_ID"/> <many-to-many class="org.hibernate.auction.Item" column="ITEM_ID"/> </bag></class><class name="org.hibernate.auction.Item"> <id name="id" column="ID"/> ... <!-- inverse end --> <bag name="categories" table="CATEGORY_ITEM" inverse="true" lazy="true"> <key column="ITEM_ID"/> <many-to-many class="org.hibernate.auction.Category" column="CATEGORY_ID"/> </bag></class></pre><p> 如果只对关联的反向端进行了改变,这个改变<span class="emphasis"><em>不会</em></span>被持久化。 这表示Hibernate为每个双向关联在内存中存在两次表现,一个从A连接到B,另一个从B连接到A。如果你回想一下Java对象模型,我们是如何在Java中创建多对多关系的,这可以让你更容易理解: </p><pre class="programlisting">category.getItems().add(item); // The category now "knows" about the relationshipitem.getCategories().add(category); // The item now "knows" about the relationshipsession.update(item); // No effect, nothing will be saved!session.update(category); // The relationship will be saved</pre><p> 非反向端用于把内存中的表示保存到数据库中。如果两端都进行了改编,我们会进行多余的INSERT/UPDATE,甚至可能得到外键冲突!这一点对双向的一对多关联也是一样的。 </p><p> 要建立一个一对多的双向关联,你可以通过把一个一对多关联,作为一个多对一关联映射到到同一张表的字段上,并且在"多"的那一端定义<tt class="literal">inverse="true"</tt>。 (原文: You may map a bidirectional one-to-many association by mapping a one-to-many association to the same table column(s) as a many-to-one association and declaring the many-valued end <tt class="literal">inverse="true"</tt>.) </p><pre class="programlisting"><class name="eg.Parent"> <id name="id" column=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -