`
hanfengmvp
  • 浏览: 20270 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

为什么双向关联的配置老是用Set 而不用 List?

阅读更多
hibernate的双向关联给我们获得关联的对象提供了很大的方便,但是Set对象却不如List对象用的那么多。hibernate本来就支持list配置的双向关联,可是为什么,资料上老是介绍set呢?
分享到:
评论
32 楼 iamprogramer 2007-08-10  
请教各位能否详细说一下set 和 list 各自的适应场景
31 楼 iamprogramer 2007-08-10  
请教各位能不能详细说一下set和list到底于哪些场景?2
30 楼 O.Lions 2007-06-14  
根据开发遇到的情况!
   自己改就是了 !
29 楼 O.Lions 2007-06-14  
根据开发遇到的情况 !
   自己看着改就是了1
28 楼 maoxiaolu2000 2007-06-06  
用List 可能排序显示上方便一点吧, 如果先在程序中set过List 并显示给用户 确认的话就会按List顺序排列了, 用set好像顺序是随机的
27 楼 obullxl 2007-06-05  
lixuehui 写道
daquan198163 写道
有什么明显的区别么
估计大多数人都是受自己看的第一本hibernate书影响来选择的,呵呵
hgq0011观点正确

        <list name="files" table="FILES">
            <key column="USER_ID"/>
            <index column="POSITION"/>  //数据库里也要有这个字段
//需要加索引值 USERID和POSITION联合做主键,既然允许放重复值,就加一个POSITION与USER_ID联合主键,保证能够准确定位到重复对象其中的某一个,放重复的对象,如果不区分出来它的位置的话,那放进去,遇到重复的,估计就找不着了
             <element type="string" column="FILENAME" not-null="true"/>
        </list>


学习中,我也一直被这个问题困扰。
26 楼 hongnaiqin 2007-05-31  
感觉用list比较方便
25 楼 Michael.zhl 2007-05-31  
用list要设置排序,用set可以过滤重复的,应该就少这也吧,根据不同需求来选择.
24 楼 一根筷子 2007-05-30  
我做了以下比较list,Set感觉还是bag不错
23 楼 dayone 2007-05-03  
感觉还是用set好一些
22 楼 wubg 2007-05-02  
谁叫你用hibernate,业务一复杂,用起来相当难受。。。左右关联之间的相对来说很难处理,一多表关联就晕(可能是本人hibernate比较浅,)虽然说h3支持xml中对sql进行注入,但是好像与hibernate最原始的初衷有点偏离,hibernate不是支持对象化了,还要进行sql注入,那还不如直接写sql进行处理,更好,也不会把不用的属性拉出来。。。。。
21 楼 smaer 2007-04-17  
没用过set,都是用list的
20 楼 janh 2007-04-17  
有个简单的办法,比较时只用id,如果比较的两个对象id都是null,那么直接返回两个对象的 == 的比较结果,因为id为null只会出现的新建对象的时候,新建时不会去建两个相同的对象吧,而且hibernate保存后生成的id肯定是不同的。
19 楼 janh 2007-04-17  
说到关联使用Set可以避免重复对象可能也只是自我感觉可靠一些,实际上不会有重复对象出现,每个关联对象都有自己的主键id,获取集合时只是简单的外键关联查询,没有复杂的查询,哪来的重复对象呢。如果集合里不是自己定义的pojo而是String、Integer等简单类型倒是可能会重复,不过那是特殊的应用了。对于hql等查询才需要考虑可能出现的重复对象问题(同一对象的重复引用),但是hibernate并没有提供返回Set的查询方法,用query.iterate()也会有重复对象。

因为相同id的对象在session中只会保存一份,所以如果始终在同一session中那么不实现equals和hashCode方法也可以放心的使用集合的contains等方法,不管是用hql查询还是load、get方法,对于同一id返回的都是同一个对象,即使对于因延迟加载而代理的对象也是始终返回该代理对象,忽然想到对于get方法如果某id前面有过代理对象,虽然一定会加载实体对象数据,但返回的还是该代理对象,以前一直觉得很奇怪,可能就是基于这样的考虑。看来OpenSessionInView方法很有好处啊。

如果要实现equals和hashCode方法,当然首先要考虑到id字段,忽然想到光id字段还不够,因为对于新建的对象,id为null,如果新建两个对象然后放到Set中,会认为两个对象相等,只能放入第一个,保存时也只能保存一个,反而不重写equals和hashCode时倒是没有问题。

好像我是在这里极力推荐使用List,其实也不是,各人有各人的习惯。
18 楼 daquan198163 2007-04-16  
嗯,这么说采用Bag(java.util.List)或者Set(java.util.Set)都是可以的啊
顺便问一下:领域对象需要重写.equals和.hashCode()么?如果需要的话应该用到id字段么?
17 楼 janh 2007-04-15  
不要误会了robbin所说的话,他所说的要特别慎用list是指的hibernate映射文件中的list类型,而不是实体类中的List类型。映射文件中用Bag类型,在实体类中是可以对应List的。

至于说排序,List(Bag映射)和Set都是可以排序的,hibernate有自己的Set、List、Map实现,其内部根据使用的排序方式使用java.util中的各种不排序的或排序的集合实现类。

Set映射有两种排序方式,一是使用映射文件中的sort属性,一般需要自己实现一个java.util.Comparator,sort属性指定自己实现的比较类,hibernate返回给客户的实际是Set的TreeSet实现,将该比较类作为treeSet的比较器,这种排序是在内存中进行的,可以在比较器中按实体类的某个字段排序或实现更复杂的排序方法,非常灵活,但是要自己实现比较器,麻烦一些。

另一种方法是使用映射中的order-by属性,可以指定表中的一个排序字段,排序是在数据库中进行的,hibernate返回是LinkedHashSet实现,可以保持对象的前后次序。

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

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

个人感觉List使用起来方便一些,所以一般在实体类中定义List,对应映射中的Bag类型。
16 楼 spiritfrog 2007-04-15  
首先应该是看是怎样的需求。如果要求没有重复,固然是用set;如果是要求保持插入数据库的先后顺序,就用list。
set需要注意equals和hashcode实现,但是list还要担心robbin说的问题,所以相比之下确实set用起来更加简单了。
至于效率的话,单看遍历的效率当然是list更高,但是hibernate要维护index列,相信多次update带来的性能牺牲肯定是比遍历要大了。
15 楼 fantasia 2007-04-15  
因为一般关联是确实是没有重复的记录,所以就是通常工具从数据库表生成映射文件就用了set,可是有时显示集合中的数据是有要保持顺序的需求,这个时候就要选用list(用bag映射的那种,用list映射的那种是需要数据库中存有索引字段,还要连续的)

list要比set效率高,因为set是把元素存在map的key所在位置上,况且list比set使用起来也要方便,list可直接用索引取值,set这一般通过iterator遍历。
14 楼 robbin 2007-04-14  
对于一对多关联当中的List,需要在数据库里面维护一个index列,如果List当中的某个元素被删除,那么Hibernate会连续发送多条update语句,更新后续所有元素的index列,以确保index的连续性(在inverse为false的情况下),如果你选择自己维护index列,也同样会面临这个问题,甚至更棘手(在inverse为true的情况下),所以List被谨慎的使用在极其罕见的场合。

一般来说,我会选择在1对关联当中使用Bag,在多对多关联当中使用Set。
13 楼 lewisou 2007-04-14  
除了上述各位说的原因外,我再补充一点。
因为1对多的关联,从逻辑上讲是无序的。
我们都知道Set是一个集合,里面的集合是无序的,而list不光光是个容器(虽然大家都把它当容器用)它是个列表,强调元素与元素的先后关系。请问我们数据库里得数据行有先后顺序吗?显然没有。元素的先后顺序是由业务逻辑决定的,比如按照出生年月排序,按照年龄排序。所以抓取出来得多个对象可以有多种排序方式。所以我们通过hibernate抓取出来的对象应该是个Set,然后更具不同的逻辑进行排序。

相关推荐

    STL上课课件1234

    顺序容器包括vector、list、deque、queue、stack、priority_queue,关联容器则包括set、multiset、map、multimap、unordered_map和unordered_multimap。这些容器各自有着不同的内部结构和用途,可满足不同的数据存储...

    C++中STL使用总结

    8. string对象与数值相互转换:可以使用标准库函数如atoi()、atol()、atof()等将string转换为数值,使用std::to_string()将数值转换为string。 十三、heap算法 Heap算法用于实现堆这种数据结构,它是一种特殊的...

    C++容器类的简单介绍.doc

    list则是一种双向链表,其优点在于能在任何位置快速插入和删除元素,但访问速度比前两者慢。 关联容器包括set、multiset、map和multimap。set和multiset提供了快速查找功能,不允许重复值,set是单值,而multiset...

    C++_标准模板库(STL)

    STL被设计为高效且易于使用,其核心在于模板的广泛应用,使得STL中的数据结构和算法与数据类型无关,从而提供了一种类型安全且高效的方式来处理数据。 STL主要包含以下几大类组件: 1. 顺序性容器:这些容器保持...

    stl标准数据库

    STL(Standard Template Library,标准模板库)是C++标准库中的一个重要组成部分,它提供了一系列模板化的数据结构和算法,以便于程序员使用。C++的STL主要包含六大组件:容器(Containers)、迭代器(Iterators)、...

    cPP.rar_c++ 容器使用_容器

    首先,C++中的容器分为几种主要类型:顺序容器(如vector、deque和list)、关联容器(如set、multiset、map和multimap)以及特殊容器(如stack、queue和priority_queue)。每个容器都有其特定的用途和性能特点。 1....

    超级有影响力霸气的Java面试题大全文档

    为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域...

    STL.rar_STL_stl queues

    STL,全称为Standard Template Library(标准模板库),是C++编程语言中的一部分,它提供了一组高效且灵活的容器、算法和迭代器,极大地增强了C++的编程能力。在这个"STL.rar"压缩包中,包含了一些关于STL的学习程序...

    stl数据结构.docx

    STL容器主要基于广泛使用的数据结构实现,涵盖了多种类型的数据结构,如数组(array)、向量(vector)、列表(list)、树(tree)、栈(stack)、队列(queue)、散列表(hash table)、集合(set)、映射表(map)等。这些数据结构...

    JAVA 面试 问题和答案

    集合框架包含List、Set、Queue等接口和实现它们的类,如ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、TreeMap等。 4.2 为什么Collection不扩展Cloneable和Serializable接口?Collection接口不实现...

    STL源码剖析高清pdf

    7. **set/map**:基于红黑树实现的关联容器,set中元素是唯一的,map则将键映射到值。set和map都提供了快速查找和插入,但插入新元素时会自动排序。 8. **算法实现**:STL还包含了各种通用算法,如排序(sort)、...

    C++_STL使用例子大全

    这篇文章介绍了如何在C++中使用STL的容器部分,包括vector、deque、list、set、multiset、map、multimap、stack、queue和priority_queue等。通过具体的代码示例,我们可以学习如何创建这些容器的实例,对它们进行...

    Java面试题和答案.pdf

    `Iterator`怎么使用?有什么特点?** - 使用`iterator()`方法获取`Iterator`对象。 - 特点包括:支持`hasNext()`和`next()`方法进行遍历;支持`remove()`方法删除元素;`Iterator`遍历比传统的`for`循环更安全,...

    C++STL讲解 PPT版本

    Set和Map是关联容器,存储键值对,Set中的元素唯一,Map中的键值对也满足键的唯一性。 2. **算法**(Algorithms):STL提供了大量的通用算法,如Sort、Search、Copy、Erase等,这些算法可以应用于不同的容器上,...

    C++ STL标准程序库开发指南

    C++ STL,全称为Standard Template Library(标准模板库),是C++编程语言中不可或缺的一部分,为程序员提供了高效且灵活的数据结构和算法。STL的主要组件包括容器、迭代器、算法和函数对象,它们通过模板机制实现,...

    C++标准模版库(Standard Template Library).pdf

    这些容器中的元素保持有序状态,并且不允许重复元素(对于`set`和`map`而言)。 ##### Set - **特点**:`set`是一个包含唯一元素的集合,其中的元素根据大小关系进行排序。 - **操作**: - `at(size_t i)`:安全...

    标准模板库STL用法

    关联容器(如`set`, `multiset`, `map`, `multimap`)主要基于树形结构实现,提供了对元素的快速查找、插入和删除操作,适合处理具有唯一性或需要根据键值进行快速查找的数据。 **1. C++ SETS&MULTISETS** - **...

Global site tag (gtag.js) - Google Analytics