解读Hibernate高级集合映射

本文主要介绍Hibernate高级集合映射(Advanced collection mappings),Hibernate高级集合映射主要分为有序集合、双向关联、双向关联,涉及有序集合类、 三重关联(Ternary associations)、使用

成都创新互联公司长期为1000多家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为赵县企业提供专业的成都做网站、网站制作,赵县网站改版等技术服务。拥有十载丰富建站经验和众多成功案例,为您定制开发。

1. 有序集合(Sorted collections)

Hibernate高级集合映射支持实现java.util.SortedMap和java.util.SortedSet的集合。你必须在映射文件中指定一个比较器:

 
 
 
  1.  name="aliases"   
  2.             table="person_aliases"   
  3.             sort="natural"> 
  4.      column="person"/> 
  5.      column="name" type="string"/> 
  6.  
  7.  
  8.  name="holidays" sort="my.custom.HolidayComparator"> 
  9.      column="year_id"/> 
  10.      column="hol_name" type="string"/> 
  11.      column="hol_date" type="date"/> 
  12.  

sort属性中允许的值包括unsorted,natural和某个实现了java.util.Comparator的类的名称。

分类集合的行为事实上象java.util.TreeSet或者java.util.TreeMap。

如果你希望数据库自己对集合元素排序,可以利用set,bag或者map映射中的order-by属性。这个解决方案只能在jdk1.4或者更高的jdk版本中才可以实现(通过LinkedHashSet或者 LinkedHashMap实现)。 它是在SQL查询中完成排序,而不是在内存中。

 
 
 
  1.  name="aliases" table="person_aliases" order-by="lower(name) asc"> 
  2.      column="person"/> 
  3.      column="name" type="string"/> 
  4.  
  5.  
  6.  name="holidays" order-by="hol_date, hol_name"> 
  7.      column="year_id"/> 
  8.      column="hol_name" type="string"/> 
  9.      column="hol_date" type="date"/> 
  10.  

注意: 这个order-by属性的值是一个SQL排序子句而不是HQL的!

关联还可以在运行时使用集合filter()根据任意的条件来排序。

 
 
 
  1. ssortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list(); 

2. 双向关联(Bidirectional associations)

双向关联允许通过关联的任一端访问另外一端。在Hibernate中, 支持两种类型的双向关联:

◆一对多(one-to-many)
Set或者bag值在一端, 单独值(非集合)在另外一端

◆多对多(many-to-many)
两端都是set或bag值

要建立一个双向的多对多关联,只需要映射两个many-to-many关联到同一个数据库表中,并再定义其中的一端为inverse(使用哪一端要根据你的选择,但它不能是一个索引集合)。

这里有一个many-to-many的双向关联的例子;每一个category都可以有很多items,每一个items可以属于很多categories:

 
 
 
  1.  name="Category"> 
  2.      name="id" column="CATEGORY_ID"/> 
  3.     ...  
  4.      name="items" table="CATEGORY_ITEM"> 
  5.          column="CATEGORY_ID"/> 
  6.          class="Item" column="ITEM_ID"/> 
  7.      
  8.  
  9.  
  10.  name="Item"> 
  11.      name="id" column="CATEGORY_ID"/> 
  12.     ...  
  13.  
  14.      
  15.      name="categories" table="CATEGORY_ITEM" inverse="true"> 
  16.          column="ITEM_ID"/> 
  17.          class="Category" column="CATEGORY_ID"/> 
  18.      
  19.  

如果只对关联的反向端进行了改变,这个改变不会被持久化。 这表示Hibernate为每个双向关联在内存中存在两次表现,一个从A连接到B,另一个从B连接到A。如果你回想一下Java对象模型,我们是如何在Java中创建多对多关系的,这可以让你更容易理解:

 
 
 
  1. category.getItems().add(item);          // The category now "knows" about the relationship  
  2. item.getCategories().add(category);     // The item now "knows" about the relationship  
  3.  
  4. session.persist(item);                   // The relationship won''t be saved!  
  5. session.persist(category);               // The relationship will be saved 

非反向端用于把内存中的表示保存到数据库中。

要建立一个一对多的双向关联,你可以通过把一个一对多关联,作为一个多对一关联映射到到同一张表的字段上,并且在"多"的那一端定义inverse="true"。

 
 
 
  1.  name="Parent"> 
  2.      name="id" column="parent_id"/> 
  3.     ....  
  4.      name="children" inverse="true"> 
  5.          column="parent_id"/> 
  6.          class="Child"/> 
  7.      
  8.  
  9.  
  10.  name="Child"> 
  11.      name="id" column="child_id"/> 
  12.     ....  
  13.      name="parent"   
  14.         class="Parent"   
  15.         column="parent_id" 
  16.         not-null="true"/> 
  17.  

在“一”这一端定义inverse="true"不会影响级联操作,二者是正交的概念!

3. 双向关联,涉及有序集合类

对于有一端是或者的双向关联,需要加以特别考虑。假若子类中的一个属性映射到索引字段,没问题,我们仍然可以在集合类映射上使用inverse="true":

 
 
 
  1.  name="Parent"> 
  2.      name="id" column="parent_id"/> 
  3.     ....  
  4.      name="children" inverse="true"> 
  5.          column="parent_id"/> 
  6.          column="name"   
  7.             type="string"/> 
  8.          class="Child"/> 
  9.      
  10.  
  11.  
  12.  name="Child"> 
  13.      name="id" column="child_id"/> 
  14.     ....  
  15.      name="name"   
  16.         not-null="true"/> 
  17.      name="parent"   
  18.         class="Parent"   
  19.         column="parent_id" 
  20.         not-null="true"/> 
  21.  

但是,假若子类中没有这样的属性存在,我们不能认为这个关联是真正的双向关联(信息不对称,在关联的一端有一些另外一端没有的信息)。在这种情况下,我们不能使用inverse="true"。我们需要这样用:

 
 
 
  1.  name="Parent"> 
  2.      name="id" column="parent_id"/> 
  3.     ....  
  4.      name="children"> 
  5.          column="parent_id" 
  6.             not-null="true"/> 
  7.          column="name"   
  8.             type="string"/> 
  9.          class="Child"/> 
  10.      
  11.  
  12.  
  13.  name="Child"> 
  14.      name="id" column="child_id"/> 
  15.     ....  
  16.      name="parent"   
  17.         class="Parent"   
  18.         column="parent_id" 
  19.         insert="false" 
  20.         update="false" 
  21.         not-null="true"/> 
  22.  

注意在这个映射中,关联中集合类"值"一端负责来更新外键.TODO: Does this really result in some unnecessary update statements?

4. 三重关联(Ternary associations)

有三种可能的途径来映射一个三重关联。***种是使用一个Map,把一个关联作为其索引:

 
 
 
  1.  name="contracts"> 
  2.      column="employer_id" not-null="true"/> 
  3.      column="employee_id" class="Employee"/> 
  4.      class="Contract"/> 
  5.  
  6.  name="connections"> 
  7.      column="incoming_node_id"/> 
  8.      column="outgoing_node_id" class="Node"/> 
  9.      column="connection_id" class="Connection"/> 
  10.  

第二种方法是简单的把关联重新建模为一个实体类。这使我们最经常使用的方法。

***一种选择是使用复合元素,我们会在后面讨论

5. 使用

如果你完全信奉我们对于“联合主键(composite keys)是个坏东西”,和“实体应该使用(无机的)自己生成的代用标识符(surrogate keys)”的观点,也许你会感到有一些奇怪,我们目前为止展示的多对多关联和值集合都是映射成为带有联合主键的表的!现在,这一点非常值得争辩;看上去一个单纯的关联表并不能从代用标识符中获得什么好处(虽然使用组合值的集合可能会获得一点好处)。不过,Hibernate提供了一个(一点点试验性质的)功能,让你把多对多关联和值集合应得到一个使用代用标识符的表去。

属性让你使用bag语义来映射一个List (或Collection)。

 
 
 
  1.  name="lovers" table="LOVERS"> 
  2.      column="ID" type="long"> 
  3.          class="sequence"/> 
  4.      
  5.      column="PERSON1"/> 
  6.      column="PERSON2" class="Person" fetch="join"/> 
  7.  

你可以理解,人工的id生成器,就好像是实体类一样!集合的每一行都有一个不同的人造关键字。但是,Hibernate没有提供任何机制来让你取得某个特定行的人造关键字。

注意的更新性能要比普通的高得多!Hibernate可以有效的定位到不同的行,分别进行更新或删除工作,就如同处理一个list, map或者set一样。

在目前的实现中,还不支持使用identity标识符生成器策略来生成集合的标识符。

【编辑推荐】

  1. Hibernate乐观并发控制
  2. Hibernate传播性持久化攻略
  3. 深入了解Hibernate自动状态检测
  4. 简单学会Hibernate对象持久化
  5. 分析Hibernate自增主键

文章名称:解读Hibernate高级集合映射
网页URL:http://www.shufengxianlan.com/qtweb/news49/249899.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联