文档章节

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

猪刚烈
 猪刚烈
发布于 2014/10/12 11:41
字数 1594
阅读 20
收藏 0
点赞 0
评论 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 ⋅ 0

Hibernate框架学习之注解映射实体类

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

Single_YAM ⋅ 2017/11/13 ⋅ 0

hibernate官方入门教程 (转载)

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

不会飞的菜鸟 ⋅ 2015/03/23 ⋅ 0

使用SQLQuery 在Hibernate中使用sql语句

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

无间道 ⋅ 2013/03/13 ⋅ 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 ⋅ 0

Hibernate操作没有主键的表

首先对于没有主键的表,要生成ORM映射的话,需要用复合主键,具体请点击复合主键。 这里想说的demo是不用生成ORM映射,通过hibernate操作表。关于建表和vo请参考复合主键链接。 下面说说具体...

开源中国驻联合国理事 ⋅ 2013/07/27 ⋅ 0

Hibernate缓存与集合性能分析

Hibernate作为一个应用级的数据访问层封装,只能在其作用范围内保持cache中数据的有效性,如果系统与第三方系统共享数据库的情况下,Hibernate的Cache机制可能失效。 Hibernate在本地JVM中维...

疯子船长 ⋅ 2015/10/26 ⋅ 0

Hibernate(2)

1、概述 2、实体对象的生命周期 3、VO与 PO 4、session接口 session管理方案: 第二种方法: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/......

学而时习之 ⋅ 2015/04/22 ⋅ 0

Hibernate框架(一)——总体介绍

作为SSH三大框架之一的Hibernate,是用来把程序的Dao层和数据库打交道用的,它封装了JDBC的步骤,是我们对数据库的操作更加简单,更加快捷。利用Hibernate框架我们就可以不再编写重复的JDBC代...

凡尘里的一根葱 ⋅ 2015/11/10 ⋅ 0

Java程序员从笨鸟到菜鸟之(五十七)细谈Hibernate(八)Hibernate集合Map关系映射

对于hibernate中,集合属性在Hibernate的映射文件中是非常常见的,也是非常重要的内容,理解和熟练掌握常用的集合属性则显得更为重要。在hibernate的配置文件中,例如每个人的考试成绩,就是典型...

长平狐 ⋅ 2012/11/12 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

来自一个优秀Java工程师的简历

写在前面: 鉴于前几天的一份前端简历,虽然带着很多不看好的声音,但却帮助了很多正在求职路上的人,不管评论怎么说,我还是决定要贴出一份后端的简历。 XXX ID:357912485 目前正在找工作 ...

颖伙虫 ⋅ 11分钟前 ⋅ 0

Confluence 6 恢复一个站点有关使用站点导出为备份的说明

推荐使用生产备份策略。我们推荐你针对你的生产环境中使用的 Confluence 参考 Production Backup Strategy 页面中的内容进行备份和恢复(这个需要你备份你的数据库和 home 目录)。XML 导出备...

honeymose ⋅ 今天 ⋅ 0

JavaScript零基础入门——(九)JavaScript的函数

JavaScript零基础入门——(九)JavaScript的函数 欢迎回到我们的JavaScript零基础入门,上一节课我们了解了有关JS中数组的相关知识点,不知道大家有没有自己去敲一敲,消化一下?这一节课,...

JandenMa ⋅ 今天 ⋅ 0

火狐浏览器各版本下载及插件httprequest

各版本下载地址:http://ftp.mozilla.org/pub/mozilla.org//firefox/releases/ httprequest插件截至57版本可用

xiaoge2016 ⋅ 今天 ⋅ 0

Docker系列教程28-实战:使用Docker Compose运行ELK

原文:http://www.itmuch.com/docker/28-docker-compose-in-action-elk/,转载请说明出处。 ElasticSearch【存储】 Logtash【日志聚合器】 Kibana【界面】 答案: version: '2'services: ...

周立_ITMuch ⋅ 今天 ⋅ 0

使用快嘉sdkg极速搭建接口模拟系统

在具体项目研发过程中,一旦前后端双方约定好接口,前端和app同事就会希望后台同事可以尽快提供可供对接的接口方便调试,而对后台同事来说定好接口还仅是个开始、设计流程,实现业务逻辑,编...

fastjrun ⋅ 今天 ⋅ 0

PXE/KickStart 无人值守安装

导言 作为中小公司的运维,经常会遇到一些机械式的重复工作,例如:有时公司同时上线几十甚至上百台服务器,而且需要我们在短时间内完成系统安装。 常规的办法有什么? 光盘安装系统 ===> 一...

kangvcar ⋅ 昨天 ⋅ 0

使用Puppeteer撸一个爬虫

Puppeteer是什么 puppeteer是谷歌chrome团队官方开发的一个无界面(Headless)chrome工具。Chrome Headless将成为web应用自动化测试的行业标杆。所以我们很有必要来了解一下它。所谓的无头浏...

小草先森 ⋅ 昨天 ⋅ 0

Java Done Right

* 表示难度较大或理论性较强。 ** 表示难度更大或理论性更强。 【Java语言本身】 基础语法,面向对象,顺序编程,并发编程,网络编程,泛型,注解,lambda(Java8),module(Java9),var(...

风华神使 ⋅ 昨天 ⋅ 0

Linux系统日志

linux 系统日志 /var/log/messages /etc/logrotate.conf 日志切割配置文件 https://my.oschina.net/u/2000675/blog/908189 logrotate 使用详解 dmesg 命令 /var/log/dmesg 日志 last命令,调......

Linux学习笔记 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部