6.2. 映射集合(Mapping a Collection)
在Hibernate配置文件中使用<set>, <list>, <map>, <bag>, <array> 和 <primitive-array>等元素来定义集合,而<map>是最典型的一个。
<map
name="propertyName" (1)
table="table_name" (2)
schema="schema_name" (3)
lazy="true|false" (4)
inverse="true|false" (5)
cascade="all|none|save-update|delete|all-delete-orphan" (6)
sort="unsorted|natural|comparatorClass" (7)
order-by="column_name asc|desc" (8)
where="arbitrary sql where condition" (9)
outer-join="true|false|auto" (10)
batch-size="N" (11)
access="field|property|ClassName" (12)
>
<key .... />
<index .... />
<element .... />
</map>
(1) name 集合属性的名称
(2) table (可选——默认为属性的名称)这个集合表的名称(不能在一对多的关联关系中使用)
(3) schema (可选) 表的schema的名称, 他将覆盖在根元素中定义的schema
(4) lazy (可选——默认为false) lazy(可选--默认为false) 允许延迟加载(lazy initialization )(不能在数组中使用)
(5) inverse (可选——默认为false) 标记这个集合作为双向关联关系中的方向一端。
(6) cascade (可选——默认为none) 让操作级联到子实体
(7) sort(可选)指定集合的排序顺序, 其可以为自然的(natural)或者给定一个用来比较的类。
(8) order-by (可选, 仅用于jdk1.4) 指定表的字段(一个或几个)再加上asc或者desc(可选), 定义Map,Set和Bag的迭代顺序
(9) where (可选) 指定任意的SQL where条件, 该条件将在重新载入或者删除这个集合时使用(当集合中的数据仅仅是所有可用数据的一个子集时这个条件非常有用)
(10) outer-join(可选)指定这个集合,只要可能,应该通过外连接(outer join)取得。在每一个SQL语句中, 只能有一个集合可以被通过外连接抓取(译者注: 这里提到的SQL语句是取得集合所属类的数据的Select语句)
(11) batch-size (可选, 默认为1) 指定通过延迟加载取得集合实例的批处理块大小("batch size")。
(12) access(可选-默认为属性property):Hibernate取得属性值时使用的策略
建立列表(List)和数组(Array)需要一个单独表字段用来保存列表(List)或数组(Array)的索引(foo[i]中的i)。如果你的关系模型中没有一个索引字段, 例如:如果你处理的是老式的遗留数据, 你可以用无序的Set来替代。这会让那些以为List应该是访问无序集合的比较方便的方法的人感到气馁。Hibernate集合严格遵守Set,List和Map接口中包涵的自然语义。 List元素不能正确的自发对他们自己进行排序!
在另一方面, 那些准备使用List来模拟bag的语义的人有一个合法的委屈(a legitimate grievance)。bag是一个无序,没有索引的集合并且可能包含多个相同的元素。在Java集合框架中没有Bag接口,但是你必须用List模拟它。Hibernate允许你映射类型为List或者Collection的属性到<bag>元素。注意: Bag语义事实上并不是Collection规范(contract)的一部分并且事实上它和List规范中的语义是相矛盾的。(然而,你可以对bag任意排序,在本章后面加以讨论。)
注意:具有inverse="false"标记的大型Hibernate bag效率是相当低的,应该尽量避免。Hibernate无法创建,删除和更新它的单个记录, 因为他们没有关键字来识别单个记录。
6.3. 值集合和多对多关联(Collections of Values and Many-To-Many Associations)
任何值集合和实体集合如果被映射为多对多关联(Java集合中的语义)就需要一个集合表。这个表中包含外键字段,元素字段还可能有索引字段。
使用<key>元素来申明从集合表到其拥有者类的表(from the collection table to the table of the owning class)的外键关键字。
<key column="column_name"/>
(1) column(必需):外键字段的名称
对于类似与map和list的带索引的集合, 我们需要一个<index>元素。对于list来说, 这个字段包含从零开始的连续整数。如果你要处理遗留的老式数据,请确保你的index真的是从0开始计数的。对于map来说,这个字段可以包含任意Hibernate类型的值。
<index
column="column_name" (1)
type="typename" (2)
/>
(1) column(必需):保存集合索引值的字段名。
(2) type (可选,默认为整型integer):集合索引的类型。
还有另外一个选择,map可以是实体类型的对象。在这里我们使用<index-many-to-many>元素。
<index-many-to-many
column="column_name" (1)
class="ClassName" (2)
/>
(1) column(必需):集合索引值中外键字段的名称
(2) class (required):(必需):集合的索引使用的实体类。
对于一个值集合, 我们使用<element>标签。
<element
column="column_name" (1)
type="typename" (2)
/>
(1) column(必需):保存集合元素值的字段名。
(2) type (必需):集合元素的类型