文档章节

关于Hibernate中对集合类型的映射

猪刚烈
 猪刚烈
发布于 2014/10/12 11:41
字数 1594
阅读 20
收藏 0

Each interface has a matching implementation
supported by Hibernate, and it’s important that you use the right combination.

 

先说一个 @JoinColumn的问题。

这个注解是用来说明关联列的信息的。

按自然的做法是:多在Many端上描述这些信息,因为从DB表上来看,关联列者是many端的表上外键列。

但是,如果是单向的one-to-many时就只能在one上映射了。这时候看起来会有些让人迷惑。

 

再补补集合中的一些知识吧,有些确实生疏了:

关于Set下面的几个具体实际的对比:

  1.  *    HashSet:哈希表是通过使用称为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放;   
  2.  *    LinkedHashSet:以元素插入的顺序来维护集合的链接表,允许以插入的顺序在集合中迭代;   
  3.  *    TreeSet:提供一个使用树结构存储Set接口的实现,通过提供元素比较器,使得集合在插入过程中直接有序。

LinkedHashSet没有实现什么特殊接口用以表明它是有序的。

 

1.关于Set的映射

在基于xml配制的情况下如果你的只是声明一个普通的set,那个在实例化对象时,hibernate会生成HashSet。

而如果在set的配制中加入order-by,hibernate就会生成LinkedHashSet了!这样就是一个有序的集合了。

 

关于Set的排序和Hibernate如何生成Set实例的问题:

 

内存排序:

Set映射有两种排序方式,一是使用映射文件中的sort属性,一般需要自己实现一个java.util.Comparator,sort属性

指定自己实现的比较类,hibernate返回给客户的实际是Set的TreeSet实现,将该比较类作为treeSet的比较器,这种

排序是在内存中进行的,可以在比较器中按实体类的某个字段排序或实现更复杂的排序方法,非常灵活,但是要自己实

现比较器,麻烦一些。

 

以下是两个例子:

 

<set name="aliases" table="person_aliases" sort="natural" >
<key column="person"/>
<element column="name" type="string"/>
</set>

 

<map name="holidays" sort="my.custom.HolidayComparator" >
<key column="year_id"/>
<map-key column="hol_name" type="string"/>
<element column="hol_date" type="date"/>
</map>

 

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

 

数据库排序:

另一种方法是使用映射中的order-by属性,可以指定表中的一个排序字段,排序是在数据库中进行的,hibernate返回

LinkedHashSet实现,可以保持对象的前后次序。

 

以下又是两个例子

<set name="aliases" table="person_aliases" order-by="lower(name) asc" >
<key column="person"/>
<element column="name" type="string"/>
</set>
<map name="holidays" order-by="hol_date, hol_name" >
<key column="year_id"/>
<map-key column="hol_name" type="string"/>
<element column="hol_date type="date"/>
</map>


所以参考中说在实体类中定义子集合时不要定义成HashSet,而应该是Set接口,因为它返回的不一定是HashSet。

对于List(Bag映射),可以指定order-by排序字段,并不需要index列。

 

关于List的影射:

首先要强调的是:很多时候,我们的java.util.List可以映射成bag的!

因为大多数时候,我们需要的只是一组从数据库里取出的数据,至于顺序,只能是从数据库中查出时的先后顺序(按ID升序)。在这种需求下,如果要使用set,那么必须要在映射中加入order-by,而如果使用list(xml中的list),那么还需要额外的index-column!所以最好的方案就是用bag.

在基于注解的配制方式时:

如果在List字段上不加@IndexColumn,那么这个List就会被映射成Hibernate里bag

 

 

1、其实hibernate是有提供list映射的, list就是bag类型,bag适合关联的集合类中有排序需求

    在配置list的时候,也有几种方法:指定list-index,这也就要在数据库中对应创建一个字段表示顺序

对于一对多关联当中的List,需要在数据库里面维护一个index列,如果List当中的某个元素被删除,那么Hibernate

连续发送多条update语句,更新后续所有元素的index列,以确保index的连续性(在inverse为false的情况下),如果

你选择自己维护index列,也同样会面临这个问题,甚至更棘手(在inverse为true的情况下),所以List被谨慎的使用在

极其罕见的场合。

    但是,这里所说的要特别慎用list是指的hibernate映射文件中的list类型,而不是实体类中的List类型。映射文件中

用Bag类型,在实体类中是可以对应List的。

 

关于@CollectionOfElements

Hibernate一直强调值对象与实体类之间差异,这在集合类型的映射上体现的极为明显。在映射集合类型的值对象进,使用xml有<element>, 使用注解则有@CollectionOfElements

 

关于@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)

 

The collection is no longer initialized if you call size(), contains(), or isEmpty().

 org.hibernate.annotations.LazyCollectionOption.EXTRA是较一般lazy loading更加lazy,或者说更加智能的选项,当访问集合的size(), contains(), or isEmpty()时,并不加载整个集合,这对加载大集合来说很适用!

 

使用了@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA),
集合变得更“聪明”,调用size()时,不会加载集合,打出的sql是:

select
        count(id)
    from
        Thread
    where
        forumId =?
  
没有使用@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.EXTRA)时,
只要用的size(),就会导致整个集合加载!以是打出的SQL 
select
        threads0_.forumId as forumId4_,
        threads0_.id as id4_,
        threads0_.id as id5_3_,
        threads0_.creationTime as creation2_5_3_,
        threads0_.forumId as forumId5_3_,
        threads0_.modifiedTime as modified3_5_3_,
        threads0_1_.subjectId as subjectId6_3_,
        post1_.id as id4_0_,
        post1_.authorId as authorId4_0_,
        post1_.creationTime as creation2_4_0_,
        post1_.isSubject as isSubject4_0_,
        post1_.messageBody as messageB4_4_0_,
        post1_.modifiedTime as modified5_4_0_,
        post1_.quotedPostId as quotedPo8_4_0_,
        post1_.title as title4_0_,
        user2_.id as id0_1_,
        user2_.accountNonExpired as accountN2_0_1_,
        user2_.accountNonLocked as accountN3_0_1_,
        user2_.credentialsNonExpired as credenti4_0_1_,
        user2_.email as email0_1_,
        user2_.enabled as enabled0_1_,
        user2_.password as password0_1_,
        user2_.username as username0_1_,
        user2_.version as version0_1_,
        post3_.id as id4_2_,
        post3_.authorId as authorId4_2_,
        post3_.creationTime as creation2_4_2_,
        post3_.isSubject as isSubject4_2_,
        post3_.messageBody as messageB4_4_2_,
        post3_.modifiedTime as modified5_4_2_,
        post3_.quotedPostId as quotedPo8_4_2_,
        post3_.title as title4_2_
    from
        Thread threads0_
    left outer join
        Thread_Subject threads0_1_
            on threads0_.id=threads0_1_.threadId
    left outer join
        Post post1_
            on threads0_1_.subjectId=post1_.id
    left outer join
        User user2_
            on post1_.authorId=user2_.id
    left outer join
        Post post3_
            on post1_.quotedPostId=post3_.id
    where
        threads0_.forumId=?

本文转载自:http://blog.csdn.net/bluishglc/article/details/5541817

共有 人打赏支持
猪刚烈
粉丝 22
博文 708
码字总数 110
作品 1
海淀
程序员
hibernate中关于bag映射(转载)

Bag是一个java集合存储元素无需关心顺序,但允许列表中的重复元素。Bag是在列表中的对象的随机分组。 Collection集合被映射在该映射表中的<bag>元件和与java.util.ArrayList中初始化。 定义R...

李永china
2016/05/09
17
0
Hibernate框架学习之注解映射实体类

前面的相关文章中,我们已经介绍了使用XML配置文件映射实体类及其各种类型的属性的相关知识。然而不论是时代的潮流还是臃肿繁杂的配置代码告诉我们,注解配置才是更人性化的设计,于是学习了...

Single_YAM
2017/11/13
0
0
hibernate官方入门教程 (转载)

hibernate官方入门教程 第一部分 - 第一个Hibernate程序 首先我们将创建一个简单的控制台(console-based)Hibernate程序。我们使用内置数据库(in-memory database) (HSQL DB),所以我们不必安...

不会飞的菜鸟
2015/03/23
0
0
使用SQLQuery 在Hibernate中使用sql语句

session.createSQLQuery.转载 对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行Session.createSQLQuery()获取这个接口。下面来描述如何使用这个API进行查询。 最基本的SQL查询就是...

无间道
2013/03/13
0
1
hibernate集合映射(转载)

POJOs如下: Customer类---->customer表 Order类对应---->orders表 customer(1)<----->(n)order public class Customer { private String id; private String username; private String pass......

李永china
2016/06/12
11
0

没有更多内容

加载失败,请刷新页面

加载更多

centos7安装Nginx

安装所需环境 一. gcc 安装 安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装: yum install gcc-c++ 二. PCRE pcre-devel 安装 PCRE(Perl Co...

狼王黄师傅
18分钟前
0
0
dubbo+apollo微服务开发指南

为了大家比较快速的开发微服务,规范dubbo,spring,mybatis,hessian,netty的版本和用法,我写了一个demo,下面对demo的功能做个简单的介绍,如有疑问的地方,可以私下问我。 微服务项目示例 ...

PageYi
20分钟前
0
0
android流式布局、待办事项应用、贝塞尔曲线、MVP+Rxjava+Retrofit、艺术图片应用等源码

Android精选源码 android模仿淘宝首页效果源码 一款艺术图片应用,采用T-MVVM打造 Android MVP + RxJava + Retrofit项目 android流式布局实现热门标签效果 android仿淘宝客户端商品详情页效果...

Android爱开源
22分钟前
2
0
一步一步安装hive

The Apache Hive ™ data warehouse software facilitates reading, writing, and managing large datasets residing in distributed storage using SQL. Structure can be projected onto d......

hnairdb
26分钟前
1
0
【WebService 系列二 使用JAX-WS开发示例程序】

1、服务端代码 1.1、编写SEI SEI即(Service Endpoint Interface)SEI在ws中称为portType,在java中称为接口 package jaxws.server;/** * @className: HelloService * @description: jax......

HansonReal
35分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部