关系:事物之间相互做用、相互联系的状态。范围最大。java
联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。sql
关联:表示对象之间的关系,既有数量性,又有方向性;动词:将对象之间经过某种方式联系起来。数据库
映射:这里指java对象和数据库表的一种对应关系。动词:造成这种对应关系。spa
级联:有关系的双方中操做一方,另外一方也将采起一些动做。hibernate
关联的联系种类code
在不考虑关联的方向前提下,联系就是关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。xml
一对一联系(1:1):如用户和身份证、一夫一妻对象
一对多联系(1:n):如班级和学生blog
多对多联系(m:n):如学生和选课开发
关联的方向:关联关系的方向可分为单向关联和双向关联。
双向关联的方向其实就不重要了,由于经过任一一方均可以维护彼此的关系。也就是说:在双向关联中一对多和多对一都是同样的。
在关联标记例如<many-to-one>或者<one-to-many>,方向都是从左到右,换句话说是由左边维护它们的关系,参见下面例子。
假设存在两张表person表和address表,它们之间的联系是n:1;
即一我的的居住地址是惟一的,一个地址却能够多我的居住。
若是在应用的业务逻辑中,仅须要每一个person实例可以查询获得其对应的Address实例,而Address实例并不须要查询获得其对应的person实例。
<class name="Person" table="person"> <id name="id" > <generator class="native"/> </id> <many-to-one name="address" column="addressId" not-null="true"/> </class> <class name="Address" > <id name="id" column="addressId"> <generator class="native"/> </id> </class>
说明:这是一个多对一的单向关联:由多的一方来维护它们的关系,须要在name="Person"的class元素内加入关联标记,<many-to-one>。这种关联很是多。
假设存在两张表person表和tel表,它们之间的联系是1:n;
即一我的的联系电话可能有多个,一个电话只能对应一我的。
若是在应用的业务逻辑中,咱们仅仅关心每一个person实例可以查询到其对应的全部tel实例,而tel实例并不须要查询获得其对应的person实例。
<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="tels"> <key column="personId" not-null="true" /> <one-to-many class="Tel"/> </set> </class> <class name="Tel"> <id name="id" column="telId"> <generator class="native"/> </id> </class>
说明:这是一个一对多的单向关联:由一的一方来维护他们的关系,须要在name="Person"的class元素内加入关联标记,<one-to-many>。这种关联相对要少一些。大部分状况下咱们都是操做多的一方的实例。
在两边同时配置单向关联,就构成了双向管理。实际开发过程当中,不少时候都是须要双向关联的,它在解决单向一对多维护关系的过程当中存在的缺陷起了必定的修补做用。
假设存在两张表person表和address表,它们之间的联系是n:1;
即一我的的居住地址是惟一的,一个地址却能够多我的居住。
既须要每一个person实例可以查询获得其对应的Address实例,Address实例也须要查询获得其对应的person实例。
<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <many-to-one name="address" column="addressId" not-null="true"/> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> <set name="people" inverse="true"> <key column="addressId"/> <one-to-many class="Person"/> </set> </class>
说明:这是一个多对一双向关联。由双方维护彼此的关系。须要在name="Person"的class元素内加入关联标记,<many-to-one>。同时在name="Address"的class元素内加入集合映射<set>,并在其中加入关联标记:<one-to-many>。
在hbm.xml中,关联标记<one-to-one>、<many-to-one>、<one-to-many>、<many-to-many>,关联的方向都是是从左到右。
简单介绍下面几个,除了name是必须,其他都是可选的。更多的咱们参考官文档。
name="对应本类的属性名"
column="映射到本表的字段名"
class="映射到本表的实体类"
unique="ture|false":(数据库外键字段生成一个惟一约束)
not-null="ture|false"默认false(数据库外键字段是否容许为空值)
lazy="ture|false"默认proxy(延迟加载)
级联的意思是指定两个对象之间的操做联动关系,对一个对象执行了操做以后,对其指定的级联对象也须要执行相同的操做
总共能够取值为:all、none、save-update、delete
all-表明在全部的状况下都执行级联操做
none-在全部状况下都不执行级联操做
save-update-在保存和更新的时候执行级联操做
delete-在删除的时候执行级联操做
集合映射标记<set>
<set name="peoples" inverse="true">
<key column="addressId"/>
<one-to-many class="Person"/>
</set>
<set name="peoples" inverse="true">name为持久化对象的集合的属性名称。
<key column="classid" > column外键的名称
<one-to-many class=“cn.edu.bzu.hibernate.Student" /> class持久化类
控制反转,主要用在一对多,多对对双向关联上,inverse能够设置到<set>集合上, 默认inverse为false。为true表示反转,由对方负责;反之,不反转,本身负责;若是不设,one和many两方都要负责控制,所以,会引起重复的sql语句以及重复添加数据。
谁是多谁是一
咱们说一对一,多对一,多对可能是谁对谁呢?在映射文件(.hbm.xml)中class元素中的对象关联标记中,好比<many-to-one>
那么class元素的属性name就是many,<many-to-one>标记中 name就是one。同时column="addressId"指明了person表的外键。
<class name="Person" table="person"> <id name="id" > <generator class="native"/> </id> <many-to-one name="address" column="addressId" not-null="true"/> </class>
上面例子中Person就是many,address就是one。
能够这么理解<many-to-one>在谁里面,谁就是many,<many-to-one>的属性name就是one。
单向关联hbm.xml配置,单向关联经常使用的是多对一,单向 many-to-one 关联是最多见的单向关联关系。这种关联是数据库关系模式中的多对一:
这个表的一个外键引用目标表的主键字段。
下面例子中的person与address联系(数据库用语)为n:1,能够这么理解:
即一我的的居住地址是惟一的,一个地址却能够多我的居住。
<class name="Person" table="person"> <id name="id" > <generator class="native"/> </id> <many-to-one name="address" column="addressId" not-null="true"/> </class> <class name="Address" > <id name="id" column="addressId"> <generator class="native"/> </id> </class>
注意:<many-to-one>标签中column="addressId",为person表添加一个外键addressId。
sql输出:
create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
双向多对一关联 是最多见的关联关系。下面的例子解释了这种标准的父/子关联关系。
下面例子中的person与address联系(数据库用语)为n:1,能够这么理解:
即一我的的居住地址是惟一的,一个地址却能够多我的居住。
<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <many-to-one name="address" column="addressId" not-null="true"/> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> <set name="people" inverse="true"> <key column="addressId"/> <one-to-many class="Person"/> </set> </class>
注意:many-to-one关联须要将one的一端加入inverse="true";column="addressId"指明了person表的外键。
sql输出:
create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
基于外键关联的双向一对一关联也很常见。
下面例子中person与address的联系(数据库用语)是1:1,能够这么理解:
即一我的只能管理一个地方,一个地方只能由一我的管理。
column="addressId"指明了person表的外键。
<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <many-to-one name="address" column="addressId" unique="true" not-null="true"/> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> <one-to-one name="person" property-ref="address"/> </class>
sql输出:
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
使用链接表的关联一般针对多对多。链接表会是数据中另外建的一张表,来存储两个实体的联系。
这张表有三个字段:自己的id,两个外键分别关联到两个实体的主键。
下面是student与course的联系(数据库用语)是m:n,能够这么理解:
一个学生能够选多门课程,一门课程也有多个学生。
<class name="Student"> <id name="id" column="studentId"> <generator class="native"/> </id> <set name="courses" table="StudentCourse"> <key column="studentId"/> <many-to-many column="courseId" class="Course"/> </set> </class> <class name="Course"> <id name="id" column="courseId"> <generator class="native"/> </id> <set name="students" inverse="true" table="StudentCourse"> <key column="courseId"/> <many-to-many column="studentId" class="Student"/> </set> </class>
注意:<set>增长了table属性,所以会另外建表。
sql输出:
create table Student ( studentId bigint not null primary key )
create table StudentCourse ( studentId bigint not null, courseId bigint not null, primary key
(studentId, courseId) )
create table Course ( courseId bigint not null primary key )