文档章节

关于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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周三乱弹 —— 我居然在 osc 里追剧

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @舆情风控小组 :分享王菲的单曲《笑忘书》 《笑忘书》- 王菲 手机党少年们想听歌,请使劲儿戳(这里) @艾尔库鲁斯:如果给大家一个选择的机...

小小编辑
36分钟前
45
4
rabbitMq的客户端使用笔记

1、channel声明队列的queueDeclare方法的参数解析 durable: 是否持久化, 队列的声明默认是存放到内存中的,如果rabbitmq重启会丢失,如果想重启之后还存在就要使队列持久化,保存到Erlang自...

DemonsI
44分钟前
0
0
“全新” 编程语言 Julia开箱体验

本文共 851字,阅读大约需要 3分钟 ! 概 述 Julia 是一个 “全新”的高性能动态编程语言,前两天迎来了其 1.0 正式版的重大更新。Julia集 Python、C、R、Ruby 之所长,感觉就像一种脚本语言...

CodeSheep
今天
11
0
软件自动化测试初学者忠告

题外话 测试入门 很多受过高等教育的大学生经常问要不要去报测试培训班来入门测试。 答案是否。 高等教育的合格毕业生要具备自学能力,如果你不具备自学能力,要好好地反省一下,为什么自己受...

python测试开发人工智能安全
今天
5
0
java并发备忘

不安全的“先检查后执行”,代码形式如下: if(条件满足){ //这里容易出现线程安全问题//doSomething}else{//doOther} 读取-修改-写入 原子操作:使用CAS技术,即首先从V中读取...

Funcy1122
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部