Hibernate(六):实体关系映射
2017-08-08 14:21
369 查看
从图上可以看出映射的分类与关系。
基本映射就是对一个实体进行映射。关系映射就是出来多个实体之间的关系,将关联关系映射到数据库中。所谓的关联关系就是对象模型中有一个或多个的引用。
关系映射就分为以下的七种:
1,多对一关联(单向)
映射原理:单向 n-1 关联只需从 n 的一端可以访问 1 的一端,既在多的一端持有一的一端的引用
实例:Product和Factory之间的关系(多个商品对应一家生产厂)。在Product的映射文件张建立多对一的关系
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.Product" table="product"> <!-- id值 --> <id name="id" column="id" type="int"> <generator class="native"/> </id> <!-- 产品名称 --> <property name="name" type="string" length="45"> <column name="name"/> </property> <!-- 产品价格 --> <property name="price" type="double"> <column name="price"/> </property> <!-- 多对一关联映射 --> <many-to-one name="factory" class="com.mr.factory.Factory"> <!-- 映射的字段 --> <column name="factoryid"/> </many-to-one> </class> </hibernate-mapping><many-to-one>元素:定义一个持久化类与另一个持久化类的关联,这种关联就是数据表之间的多对一关联,需要此持久化类映射表的外键引用另一个持久化类映射表的主键,也就是映射的字段。
name:持久化类中的的属性
column: 设定和持久化类的属性对应的表的外键
class:关联的目标持久化类
2.一对多关联(单向)
一对多和多对一的映射原理是一致的,存储是相同的,也就是生成的数据库之间的表时一样的。不同的是他们之间的维护关系。
多对一的维护关系:多指向一的关系,有了此关系,加载多的时候可以将一加载上来
一对多的维护关系:一指向多的关系,有了此关系,夹杂一的时候可以将多加载上来
3.一对多关联(双向)
映射原理: Hibernate既可以通过主控方实体加载被控方实体,也可以通过被控方加载对应的主控方实体
实例:由于一个生产商可以对应多件产品,在Factory类中以集合的形式引入Product对象,在映射文件中通过<set>标签进行映射
Factory的映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 产品信息字段配置信息 --> <hibernate-mapping> <class name="com.mr.factory.Factory" table="tab_factory"> <!-- id值 --> <id name="factoryId" column="factoryid" type="int"> <generator class="native"/> </id> <!-- 生产商名称 --> <property name="factoryName" type="string" length="45"> <column name="factoryname"/> </property> <!-- 定义一对多映射 --> <set name="products" inverse="true" > <key column="factoryid"/> <one-to-many class="com.mr.product.Product"/> </set> </class> </hibernate-mapping>
<set> 元素来映射持久化类的 set 类型的属性
name: 设定待映射的持久化类的属性的
inverse:决定是由双向关联的的哪一方来维护表与表之间的关系,false的为主动方, true为被动方,由主动方负责维护关系。(在多对一的关系中,如果将“一”设为主动方:会额外的多出update语句,插入数据时无法同时插入外键列)。这个属性只影响数据的存储
order-by:如果设置该属性,当Hibernate通过select语句到数据库检索集合对象时,利用order by语句进行排序
<key> 元素设定与所关联的持久化类对应的表的外键
column: 指定关联表的外键名
注意:
当 Session 从数据库中加载 Java 集合时, 创建的是 Hibernate 内置集合类的实例, 因此在持久化类中定义集合属性时必须把属性声明为 Java 接口类型
Hibernate 的内置集合类具有集合代理功能, 支持延迟检索策略
事实上, Hibernate 的内置集合类封装了 JDK 中的集合类, 这使得 Hibernate 能够对缓存中的集合对象进行脏检查, 按照集合对象的状态来同步更新数据库。
在定义集合属性时, 通常把它初始化为集合实现类的一个实例. 这样可以提高程序的健壮性, 避免应用程序访问取值为 null 的集合的方法抛出 NullPointerException
代码:
public class Factory { private Integer factoryId;//生产商的id private String factoryName;//生产商名称 private Set<Product> products;//Set集合,一个厂商所对应的所有图书 ..... }
4.一对一主键关联
映射原理: 一对一主键关联是指两个表之间通过主键形成一对一的映射(两个实体对象是一对一的关联映射)。
基于主键的映射策略:指一端的主键生成器使用foreign策略,表明根据“对方”的主键来生成自己的主键,自己并不能独立生成主键
利用 foreign主键生成策略的一端增加one-to-one 元素映射关联属性,其one-to-one属性还应增加 constrained=“true” 属性;另一端增加one-to-one元素映射关联属性。
实例:每个公民只允许拥有一个身份证,公民与身份证就是一对一关系。定义两个数据表,分别有两个表people(公民表)和idcard(身份证表)。其中的people中的id既是该表的主键和外键。
people的映射文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 公民信息字段配置信息 --> <hibernate-mapping> <class name="com.mr.people.People" table="tab_people"> <!-- id值 --> <id name="id" column="id" type="int"> <generator class="native"/> </id> <!-- 公民姓名 --> <property name="name" type="string" length="45"> <column name="name"/> 4000 ; </property> <!-- 公民性别 --> <property name="sex" type="string" length="2"> <column name="sex"/> </property> <!-- 公民年龄 --> <property name="age" type="int"> <column name="age"/> </property> <!-- 一对一映射 --> <one-to-one name="idcard" class="com.mr.idcard.IDcard" cascade="all"/> </class> </hibernate-mapping>idcard的映射文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 公民身份证字段信息配置信息 --> <hibernate-mapping> <class name="com.mr.idcard.IDcard" table="tab_idcard"> <!-- id值 --> <id name="id" column="id" type="int"> <!-- 外键生成 --> <generator class="foreign"> <param name="property">people</param> </generator> </id> <!-- 公民身份证号 --> <property name="idcard_code" type="string" length="45" not-null="true"> <column name="IDcard_code"/> </property> <one-to-one name="com.mr.people.People //一对一映射 constrained="true"/> </class> </hibernate-mapping>
cascade(级联)操作是指当主控方执行save,update或delete操作时,关联对象(被控方)是否进行同步操作。在映射文件中使用cascade属性进行操作
在对象 – 关系映射文件中, 用于映射持久化类之间关联关系的元素, <set>, <many-to-one> 和 <one-to-one> 都有一个 cascade 属性, 它用于指定如何操纵与当前对象关联的其他对象.
constrained(约束):指定当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联对象所对应的数据库表的 主键
一对一主键关联的缺点:
灵活性差,没有办法改成多对一的关联映射,不能应变多变的需求
必须先保存关联对象idcard,才能保存people
一般,在映射一对一单行关联映射时采用外键关联映射
5.一对一外键关联
基于外键的一对一关联,其外键可以存放在任意一端,在需要存放外键一端,增减many-to-one元素,为其添加unique="true”属性来表示1-1关联
实例:用身份证实例对象和公民实例对象为例。在people表添加一个新的字段card_id,作为该表的外键,同时需要保证该字段的唯一性
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- 公民信息字段配置信息 --> <hibernate-mapping> <class name="com.mr.people.People" table="tab_people"> <!-- id值 --> <id name="id" column="id" type="int"> <generator class="native"/> </id> <!-- 公民姓名 --> <property name="name" type="string" length="45"> <column name="name"/> </property> <!-- 公民性别 --> <property name="sex" type="string" length="2"> <column name="sex"/> </property> <!-- 公民年龄 --> <property name="age" type="int"> <column name="age"/> </property> <!-- 一对一映射 --> <many-to-one name="idcard" unique="true"> <column name="card_id"/> </many-to-one> </class> </hibernate-mapping>
上面讲的一对一的主键和外键关联映射,下来是双向的关联映射
双向关联映射原理:原理和单向的映射相同,只不过是可以从两端加载另一端。双向关联映射并不影响存储,只影响加载。双向关联映射和单向关联映射的数据库表的结构相同。只需要在另一端实体对象的映射文件中加入对另一个的引用,主键关联和外键关联的使用如上。
6.多对多关联(单向)
与一对一和多对一关联联系不同,需要通过另外一张表保存多对多的映射关系 。与一对多的映射类似,必须为set集合元素添加key子元素。与一对多映射不同的是,集合的中的元素使用的是many-to-many。
<many-to-many>元素:
class:指定集合存放的对象
7.多对多关联(双向)
和单向相同的是:使用连接表,集合属性添加key元素用于映射外键列,集合元素里添加<many-to-many>子元素关联实体类
双向关联需要两端使用集合属性
<set>集合属性:
在双向关联的两边都需要指定连接表的表名及外键列的表名。
两个集合元素的set的table值必须指定,并且相同。
set元素中的两个子元素:key和many-to-many都必须指定column属性。key和column分别指定的 是本持久化类和关联类在连接表中的外键列名。因此,两边的两个属性交叉 相同
必须把其中的一端的inverse设置为true,否则两端都维护关联关系可能会造成主键冲突
实例:应用系统的权限分配:用户可以有多个系统的操作权限,一个权限又可以赋给多个用户。
由于是多对多的关系,所以实体对象User和Role是相互引用的关系,需要在实体对象中引入Set集合。
Role
public class Role {
private Integer id;//唯一性标识
private String roleName;//权限名称
private Set<User> users;//引用的用户实体对象集合
....
}User
public class User {
private Integer id;//唯一性标识
private String name;//用户名称
private Set<Role> roles;//引用的权限实体对象集合
....
}
User.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- User实体对象 -->
<hibernate-mapping>
<class name="com.mr.user.User" table="tab_user">
<!-- 主键id -->
<id name="id">
<generator class="native"/>
</id>
<!-- 用户名称 -->
<property name="name" not-null="true" />
<set name="roles" table="tab_mapping">
<key column="user_id"></key>
<many-to-many class="com.mr.role.Role" column="role_id"/>
</set>
</class>
</hibernate-mapping>
Role.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Role实体对象 -->
<hibernate-mapping>
<class name="com.mr.role.Role" table="tab_role">
<!-- 主键id -->
<id name="id">
<generator class="native"/>
</id>
<!-- 权限名称 -->
<property name="roleName" not-null="true">
<column name="rolename"/>
</property>
<set name="users" table="tab_mapping">
<key column="role_id"></key>
<many-to-many class="com.mr.user.User" column="user_id"/>
</set>
</class>
</hibernate-mapping>可以从两个实体对象的的映射文件得出:两个之间连接表为tab_mapping
总结:
(1)从对象的加载方式看,关系映射分为两种:单向和双向。单向和双向只影响数据的加载,而不是数据的存储。生成的数据库的表是相同的。它们的不同是由对象模型决定的
(2)从对象的映射关系来看,分为四种:一对一的,一对多,和多对一和多对多的。不同是每个在两端的限制不同
相关文章推荐
- Hibernate实体关系映射——单边的多对多关系
- Hibernate实体关系映射
- 4、Hibernate 实体关系映射(一、单边一对多关系 注解、xml两种方式)
- javaEE 用户、部门、角色、权限实体的关系设计与hibernate映射配置文件关系总结
- Java Web整合开发(23) -- Hibernate实体关系映射
- Hibernate实体映射关系
- Hibernate之jpa实体映射的三种继承关系
- Hibernate实体关系映射——双边的多对多关系
- Hibernate级联查询实体关系映射
- Hibernate实体映射文件多对多等关系简单应用技巧
- Hibernate两种实体关系映射详解
- Hibernate实体关系映射——单边的一对一关系
- Hibernate实体关系映射—Annotation
- Hibernate实体映射文件多对多等关系简单应用技巧
- Hibernate实体关系关联映射中配置文件的编写
- Hibernate实体关系映射——单边的一对一关系
- Hibernate之实体关系映射
- Hibernate实体映射属性关系
- Hibernate实体关系映射:单向主键一对一关联
- Hibernate实体关系映射——主键相同的一对一关系