hibernate之Collection类型

  • Collection类型:

在Hibenrate中的一对多,多对多关系中,Collection占着比较重要的地位;在Hibernate中支持几种类型的Collection?他们之间的差异何在?

在Hibernate中涉及的Collection类型(传统的java Set,Map,List实现不能满足要求,Hibernate根据这些接口提供了自己的实现,下面的Set,Bag,Map均指的是HIbernate中的实现)有:

1,无序集合:Set,Bag,Map;

2,有序结合:List;

无序和有序,是针对HIbenate数据持久过程中的,是否保持数据集合中的记录排列顺序加以区分的;有序集的数据集合,HIbernate在持久化过程中,会将集合中元素排序的先后顺序同时固化到数据库中(以某个特定的字段值储存顺序),当读取时,也会返回一个具备同样个排列顺序的数据集合;

  • set

HIbernate Set遵循java Collection中关于Set的定义,即集合中不允许出现两个相同元素;

TUser user = new TUser();
user.setName("keith");
set.add(user);
set.add(user);
System.out.println("user size:"+user.size());

 虽然执行了两次add()操作,但是Set结构中只包含了一个引用;

Hibernate在返回关联对象集合的时候,会自动为每个记录构建一个实体对象;如:TUser对象中有 Set<Book> books属性;在添加的时候添加了5本Book;那么hibernate就会构造出5个Book对象,放在TUser的Set<Book> books集合中返回,即使这5个book记录的逻辑内容完全相同(id不同);这是通过实体对象进行映射,如果通过String对book表中的字段进行映射,就会出现问题。将映射的类型改为String(原来为com.keith.Book);那么hibernate就会只构造出一条记录进行返回(因为java.lang.String会比较两个字符串的内容,如果这样比较的话5个book内容是一样的,那么Set中又不允许出现同样的值,这样的话就会保存1条记录);添加湿这样,那么删除也会出现相同的错误;

为了补充Set数据类型在这方面的限制,HIbernate提供了Bag类型;

  • Bag
Bag:是Hibernate自定义的集合类型,实现了一个允许包含重复元素的“set”;它的底层是接触了list实现,却屏蔽了List的有序性,通过“bag”声明的数据集合,其元素排序顺序不会被持久化;
当我们将<set>替换成<bag>时;即使加入了相同的book,也会往数据库里添加了3条记录;
bag集合为无序集合,且允许出现重复元素,也会带来问题,当删除某个元素的时候,我们该如何定位这条记录?因为数据库里存在多条相同的元素,bag的实现方式,实际上是先将库表中原有的集合数据全部删除,再将现有的数据逐条插入,但是这种方式的数据更新的性能很低;对于这样的情况,如果集合中的每个元素都有一个id可以唯一检索到对应的数据库记录。
那么出现了idBag,作为bag的一种延伸,则可以解决这个问题;
<idbag name="books" lazy="true" table="_books"> 
			<collection-id type="int" column="id">
				<generator class="identy"></generator>
			</collection-id>
			<key column="user_id" />
			<element type="string" column="books"/>
		</idbag>
 更详细的可查看hibernate官方文档;
  • Map
Map也是一个无序集合类型,与Set/Bag类型不同的是,Map提供了值/键对应关系;一个Map配置例子如下:
<map name="books" lazy="true" table="_books">
			<key column="user_id"/>
			<index type="string" column="type"/>
			<element type="string" column="books"/>
		</map>
 与set配置相比,Map增加了一个<index>配置,用于指定用作Key的字段名,此字段要求在数据集中取值唯一;
  • List
List实现了集合内元素顺序的持久化,与Map集合需要额外字段保存键值一样,它要求库必须配属对应的字段以保存次序的信息;一个List配置例子如下:
<list name="books" lazy="true" table="_books">
			<key column="user_id"/>
			<index type="integer" column="idx"/>
			<element type="string" column="books"/>
		</list>
 <index />节点中,我们指定以“idx”字段保存次序状态;

相关推荐