`
hanfengmvp
  • 浏览: 20133 次
  • 性别: 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,然后更具不同的逻辑进行排序。

相关推荐

Global site tag (gtag.js) - Google Analytics