List是一个有序集合,所以当其生成简单表的时候,需要指定其下标(通过list-index标签),并且需要指定其表的名字。List所对应的表中以一个外键和下标作为联合主键。
一个简单的例子,list中存储的是简单的数据类型:
建立表的时候用的SQL语句:
//移除外键关系,防止删除的时候禁止删除
alter table children drop foreign key
FK62EA5DFF7EA87F47
//如果存在parent和children表,则删除
drop table if exists children
drop table if exists parent
//新建一个children表
create table children (id integer not null,
name varchar(255), num integer not null, primary key (id, num))
//新建一个parent表
create table parent (id integer not null,
age integer, name varchar(255), primary key (id))
//为list表添加一个一个索引序列,并且增加了一个外键约束
alter table children add index FK62EA5DFF7EA87F47 (id), add constraint FK62EA5DFF7EA87F47 foreign key (id) references parent (id)
<!-- 该类中的list作为一个表存储的,需要指定其表的名字 -->
<list name="children"
table="children">
<!--
id指的是children中的外键,也就是标识该记录属于哪一个 -->
<key
column="id"/>
<!--
这个是有序表的下标,从另一个角度而言,也可以唯一的确定某一个元素 -->
<list-index
column="num"/>
<!--
表中的元素,有且只有一个元素
-->
<element
type="string" column="name"/>
一个简单的插入测试
Hibernate: select max(id) from parent
Hibernate: insert into parent (age, name,
id) values (?, ?, ?)
Hibernate: insert into children (id, num,
name) values (?, ?, ?)
Hibernate: insert into children (id, num,
name) values (?, ?, ?)
Hibernate: insert into children (id, num,
name) values (?, ?, ?)
Set
与list的差别就在于set是一个无序的集合,所以它不需要存储下标,即需不要list-index标签。一般而言自动生成的表是不带主键的,但是如果element元素设置为not-null则会将set中的元素和外键联合作为主键(但是,一般而言没有这个必要的,因为当数据量很大的时候,主键并不能起多大作用)。
建表SQL语句和list一样:
alter table children drop foreign key
FK62EA5DFFFA0F22FC
drop table if exists children
drop table if exists parent
create table children (parent_id integer
not null, name varchar(255))
create table parent (id integer not null,
age integer, name varchar(255), primary key (id))
alter table children add index FK62EA5DFFFA0F22FC (parent_id), add constraint FK62EA5DFFFA0F22FC foreign key (parent_id) references
parent (id)
<set
name="children" table="children">
<!-- 集合属性的外键列 -->
<key column="parent_id"/>
<!-- 集合属性中的元素 -->
<element type="string"
column="name"/>
插入测试:
Hibernate:
select max(id) from parent
Hibernate:
insert into parent (age, name, id) values (?, ?, ?)
Hibernate:
insert into children (parent_id, name) values (?, ?)
Hibernate:
insert into children (parent_id, name) values (?, ?)
Hibernate: insert into children (parent_id, name) values (?, ?)
Bag
Bag元素可以为所有实现Collection接口的类进行属性映射,并且将其映射为无序集合,并且集合对应的表没有主键。其形式和set及其类似。
建表语句和list、set一样:
alter table children drop foreign key FK62EA5DFFA72135C8
drop table if exists children
drop table if exists parent
create table children (person_num integer not null, name
varchar(255))
create table parent (id integer not null, age integer, name
varchar(255), primary key (id))
alter table children add index FK62EA5DFFA72135C8 (person_num), add constraint FK62EA5DFFA72135C8 foreign key
(person_num) references parent (id)
<bag
name="children">
<key
column="person_num"/>
<element type="string"
column="name"/>
插入测试:
Hibernate:
select max(id) from parent
Hibernate:
insert into parent (age, name, id) values (?, ?, ?)
Hibernate:
insert into children (person_num, name) values (?, ?)
Hibernate:
insert into children (person_num, name) values (?, ?)
Hibernate: insert into children (person_num, name) values (?, ?)
Map
Map对应于java中的map接口,那么它存储的内容无意就是键-值信息了,外加一个外键。显然,它是将map的key和外键联合起来作为主键的。
生成的建表语句:
alter
table children drop foreign key FK62EA5DFF9987B23F
drop
table if exists children
drop
table if exists parent
create
table children (parent_map_id integer not null, sex varchar(255), name
varchar(255) not null, primary key (parent_map_id, name))
create
table parent (id integer not null, age integer, name varchar(255), primary key
(id))
alter table children add index FK62EA5DFF9987B23F (parent_map_id), add constraint
FK62EA5DFF9987B23F foreign
key (parent_map_id) references parent (id)
<map
name="children">
<!-- 映射外键 -->
<key
column="parent_map_id"/>
<!-- map的key -->
<map-key type="string"
column="name"/>
<!-- map的value -->
<element type="string"
column="sex"/>
插入测试:
Hibernate:
select max(id) from parent
Hibernate:
insert into parent (age, name, id) values (?, ?, ?)
Hibernate:
insert into children (parent_map_id, name, sex) values (?, ?, ?)
Hibernate:
insert into children (parent_map_id, name, sex) values (?, ?, ?)
Hibernate:
insert into children (parent_map_id, name, sex) values (?, ?, ?)
总结:
集合名字
|
标签名
|
备注
|
List
|
<list>
|
需要指定下标标签,其主键为:外键和下标联合形成
|
Set
|
<set>
|
如果<element>元素的not-null属性设置为true,则将外键和element内容联合设置为主键,否则没有主键
|
Collection
|
<bag>
|
没有主键
|
Map
|
<map>
|
其中map-key的not-null属性默认值为true,其主键为map的键值和外键联合组成的
|
性能对比总结:
当集合中元素内容很多很多的时候(例如十万),在初始化持久化类的时候,要完成所有集合属性的加载,势必将导致性能急剧下降。所以就产生了延迟加载策略:lazy=”true”。
无序、有序集合的优缺点:
有序集合由<key>和<index>组成的联合主键,在这种情况下,集合属性的更新是非常高效的(主键已经被有效的索引)。
无序集合中,如果<element>元素设置为非空,那么也会有主键,但是如果此时<element>元素是组合元素或者为大量文本、二进制字段,那么数据库的主键就显得那么的庞大,使得检索性能变得很差。
=====================================
复杂类型的映射:
当一个模型中有一些属性为复杂类型的时候(例如是一个类的实例),需要用到<component>标签。此标签只是将一个表中某些耦合度很强的内容写在另一个类中,但是表现到数据库中仍和其他属性在一个表中。
其建表语句为:
drop
table if exists parent
create table parent (id integer not null, age integer, name
varchar(255), first varchar(255), last varchar(255), primary key (id))
<!-- 特别的,此处需要指定class属性,unique属性不是强制性的设置为ture,二十根据实际情况设定 -->
<component
name="component" class="com.dong.model.Name"
unique="true">
<!-- 罗列出Name中的所有变量,并将其映射到数据库中的属性列 -->
<property name="firstName"
column="first"/>
<property name="lastName"
column="last"/>
那么如果集合中的属性为复杂属性的时候,需要做怎样的配置呢,其实也很简单的,只是将配置文件进行修改即可:
<set
name="children" table="children">
<!-- 集合属性的外键列 -->
<key column="parent_id"/>
<!-- 集合属性中的元素 -->
<composite-element class=”com.dong.model.Name”>
<!—映射每一个属性 -->
<property name=”firstName”/>
<property name=”lastName”/>
<composite-element>
那么如果一个模型的主键为一个复杂属性的时候,又需要做如何的配置呢,也很简单,只需要用<composite-id>代替<id>即可。但是需要注意的是,作为主键的复杂属性所对应的类必须要重写equals()和hashCode()方法,并且要实现serializable接口,其实这个原因也很容易想得到:重写那两个方法,只是为了确定主键的唯一性,实现比较对比;实现serializable接口是为了方便其存储到文件中,并且当从数据库中按照主键读取内容是,需要传递该类的一个实例(必须给主键赋值),也就是get的第二个实现serializable的参数。
下面是他的配置:
<class
name=”com.dong.model.Person” table=”person”>
<!—此标签的功能就相当于id标签的功能 -->
<composite-id name=”name” class=”com.dong.model.Name”>
<!—将Name类中的所有变量映射到表中的属性列 -->
<key-property name=”firstName”/>
<key-property name=”firstName”/>
</composite-id>
</class>
注意:hibernate是不推荐使用此方法的,因为主键越复杂,那么使得表的检索变得越困难,而且此处是使用的是联合主键使得检索变得更加的困难。
当然,如果模型的主键为一个复杂属性的时候,也可以将其复杂属性写在模型类中,没有必要新建一个类存储,但是也需要重写equals()和hashCode()方法,并且仍然需要实现serializable接口,但是在equals方法和hashCode方法中只需要操作、判断将要作为主键的变量即可,无需考虑其它的变量,原因也显然而知,主键就是用来决定表的唯一性。
其配置文件和上面的那个及其相似,但是不需要为<composite-id>标签指定name和class属性:
<class
name=”com.dong.model.Person” table=”person”>
<!—此标签的功能就相当于id标签的功能 -->
<composite-id>
<!—将Name类中的所有变量映射到表中的属性列 -->
<key-property name=”firstName”/>
<key-property name=”firstName”/>
</composite-id>
</class>
分享到:
相关推荐
在Java的持久化框架Hibernate中,集合映射是将数据库中的表关系映射到对象模型中的集合类,如List、Set、Map等。这允许我们在Java代码中操作对象集合,而Hibernate负责处理底层的SQL查询和数据存储。本文将深入探讨`...
关于标签:“源码”和“工具”,这暗示了这篇博文可能深入解析了Hibernate框架内部关于bag集合映射的源代码实现,并提供了实用的工具或技巧来帮助开发者理解和使用这一特性。源码分析有助于理解Hibernate的工作原理...
集合映射是Hibernate中一个非常关键的概念,它使得Java集合类如List、Set、Map等能够与数据库中的多对一、一对多、多对多关系对应起来。在这个主题中,我们将深入探讨Hibernate集合映射的各个方面。 首先,我们来看...
1. **XML配置**:在Hibernate的映射文件(.hbm.xml)中,使用`<list>`标签定义List集合映射。例如: ```xml ``` 这里的`name`属性指定了集合属性名,`table`是对应的数据库表名,`key`表示外键字段,`index...
在Hibernate中,标签(Annotations)是用于定义对象与数据库表之间的映射关系的一种方式,它们直接在类或属性上进行注解,使得代码更简洁、易读。本文将详细介绍Hibernate中的主要标签及其用法。 1. **@Entity** ...
在“CollectionMapping”这个示例程序中,你将看到如何在Hibernate配置文件中定义这些集合映射,以及如何在实体类中声明和使用它们。通过实践这些范例,你将更深入地了解Hibernate的集合映射机制,并能熟练地应用于...
2. **集合映射配置**:在Hibernate的映射文件(.hbm.xml)中,我们需要为集合属性配置对应的标签。例如,对于List,我们可以使用`<list>`标签,对于Set使用`<set>`,对于Map使用`<map>`,并指定对应的键(key)和值...
在给定的文档中,我们看到一个例子,展示了如何在 Hibernate 中配置一个具有集合属性的实体类 `Person`,以及如何通过映射文件启用延迟加载。`Person` 类拥有一个 `Set<Address>` 类型的 `addresses` 属性,表示个人...
Set是不允许重复元素的集合,它的映射在Hibernate中通常使用`<set>`标签来定义。在提供的代码片段中,`Customer`类有一个`Set<Order>`类型的属性`orders`,这表示一个客户可以有多个订单。在Hibernate映射文件中,`...
总之,Hibernate集合映射是对象关系映射的重要组成部分,理解并熟练掌握各种映射类型、级联操作、缓存策略等,将有助于我们在实际开发中更高效、更灵活地处理数据库与Java对象之间的关系。在实践中,不断调整和优化...
在Java持久化框架Hibernate中,容器映射技术是将Java集合类(如Set、Map、List等)与数据库中的关联关系进行映射的一种方法。这种技术使得对象之间的复杂关系能够被有效地存储和检索,增强了数据操作的灵活性。下面...
在这个"Spring-Hibernate的通过标签分页源码"中,我们可以深入理解如何在前端和后端实现基于Display Tag的分页功能。 Display Tag是一个开源的JSP标签库,它提供了很多用于表格展示和分页的功能,极大地简化了Web...
你可以使用标签替代标签来定义你的组件集合。 ; <composite-element class="eg.Name"> <!-- class attribute required --> ; 注意,如果你定义的Set包含组合元素(composite-element),正确地...
**标题:“Hibernate集合的映射”** 在Java的持久化技术中,Hibernate是一个非常重要的ORM(对象关系映射)框架,它允许开发者用面向对象的方式来处理数据库操作。本篇文章主要探讨的是Hibernate中对象与数据库表...
在探讨Hibernate中List信息的配置时,我们主要聚焦于如何在ORM(对象关系映射)框架下有效地管理和操作集合类型,尤其是List、Set以及Map。本文将深入解析List与Set在Hibernate中的映射机制,同时也会简要提及Map的...
以下是从标题、描述、标签以及部分内容中提炼出的关键知识点: ### Hibernate概述 Hibernate是Java平台下的一款开源的对象关系映射(ORM)框架,它提供了一种解决方案,用于将面向对象的Java应用程序与关系型...
而 Classes 类中也有一个 Student 的集合,表示一个班级可以有多个学生。 以下是关键知识点: 1. **一对一关系**:在 Student 类和 Address 类中,我们看到一个典型的一对一关系。在 Student 类中,有一个 Address...
通过分析这些文件,我们可以了解到如何在XML映射文件中定义集合映射,以及在Java实体类中如何使用这些映射。同时,通过运行这些示例,可以实际体验到集合映射在操作数据时的便利性。 总的来说,Hibernate的集合映射...
本文将深入讲解Hibernate中的集合映射,包括set、list、map和bag的配置与使用。 1. **Set集合映射** Set集合不允许有重复元素,因此在Hibernate中,set映射通常用于表示唯一性关系,如一对多关系。在Hibernate映射...