1. 多表设计
1.1 表之间的关系划分
- 一对一
- 一对多(多对一)
- 多对多
2. 如何确立和实现数据库中的表关系
2.1 一对多的表关系在数据库中如何实现?
使用外键约束。我们一般习惯把一的方称为主表,把多的一方称为从表。
什么是外键:
从表中有一列,该列的取值除了null之外,只能来源于主表的主键。默认情况下,外键字段的值是可以重复的。
2.2 多对多的表关系在数据库中如何实现?
使用中间表。中间表中只有两个外键,引用两个多对多表的主键。不能有其他字段信息,至于中间表的主键,应该采用联合主键。
任何一个多方的表和中间表去比较,都是一对多的关系。
2.3 一对一的表关系在数据库中如何实现?
有两种:
-
第一种:建立外键的方式:
使用外键约束,唯一约束,非空约束。它是把外键字段加了非空和唯一约束。从而实现了一对一。
-
第二种:使用主键的方式:
让其中一张表既是主键,又是外键。
2.4 如何确立两张表之间的关系:
找外键。
3. 学习多表映射配置要遵循的步骤
- 第一步:确定两张表之间的关系
- 第二步:在数据库中实现两张表之间的关系建立
- 第三步:在实体类中描述出两个实体之间的关系
- 第四步:在映射配置文件中建立两个实体和两张表之间的关系
4. 一对多关系映射配置
示例:客户和联系人两张表
4.1 确定两张表之间的关系
一个客户可以包含多个联系人,多个联系人可以属于同一个客户。所以:客户和联系人之间的关系是一对多。
4.2 在数据库中实现两张表之间的关系建立
实现一对多的关系,靠外键。客户表是主表,联系人表是从表。我们需要在联系人表中添加外键。
4.3 在实体类中描述出两个实体之间的关系
主表的实体类应该包含从表实体类的集合引用,从表的实体类应该包含主表实体类的对象引用
/**
* 客户实体类
*
* @author wgy
*/
public class Customer implements Serializable {
private Long custId;
private String custName;
private String custSource;
private String custIndustry;
private String custLevel;
private String custAddress;
private String custPhone;
/**
* 一对多关系映射:一的一方
* 主表实体应该包含从表实体的集合引用
*/
private Set<LinkMan> linkmans = new HashSet<LinkMan>(0);
...
}
/**
* 联系人的实体类
*
* @author wgy
*/
public class LinkMan implements Serializable {
private Long lkmId;
private String lkmName;
private String lkmGender;
private String lkmPhone;
private String lkmMobile;
private String lkmEmail;
private String lkmPosition;
private String lkmMemo;
/**
* 一对多关系映射,多的一方。
* 从表实体包含主表实体的对象引用
*/
private Customer customer;
...
}
4.4 在映射配置文件中建立两个实体和两张表之间的关系
客户配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 在实体类所在的包下,创建一个xml文件。该文件建议名称为:实体类名称+.hbm+.xml导入约束:dtd约束 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.wgy.domain">
<class name="Customer" table="cst_customer" lazy="true">
<id name="custId" column="cust_id">
<generator class="identity"/>
</id>
<property name="custName" column="cust_name"/>
<property name="custSource" column="cust_source"/>
<property name="custIndustry" column="cust_industry"/>
<property name="custLevel" column="cust_level"/>
<property name="custAddress" column="cust_address"/>
<property name="custPhone" column="cust_phone"/>
<!-- 一对多关系映射:主表实体的映射配置
涉及的标签:
set:
作用:用于配置set集合属性。
属性:
name:指定实体类中set集合的属性名称。
table:指定从表的名称。在一对多配置时可以不写。
key:
作用:用于映射外键字段。
属性:
column:指定外键字段名称
one-to-many:
作用:用于建立一对多的映射配置
属性:
class:用于指定从表实体的名称
-->
<set name="linkmans" table="cst_linkman">
<key column="lkm_cust_id"/>
<one-to-many class="LinkMan"/>
</set>
</class>
</hibernate-mapping>
联系人配置文件:
<?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 package="com.wgy.domain">
<class name="LinkMan" table="cst_linkman">
<id name="lkmId" column="lkm_id">
<generator class="identity"/>
</id>
<property name="lkmName" column="lkm_name"<