第三天
1、数据库中的表关系
- 一对一
- 一对多(多对一)
- 多对多
2、如何确立数据库中和实现的表关系
- 一对多的表关系在数据库中如何实现?
使用外键约束。(习惯把一的称为主表,多的称为从表)
(外键:取值除了null之外,只能来源于主表。默认情况下外键的值是可以重复的) - 多对多的表关系在数据库中如何实现?
使用中间表。(中间表只能有两个外键,引用两个多 表的主键,主键是联合主键) - 一对一的表关系在数据库中如何实现?
两种方式:- 第一种:使用外键约束,唯一约束。非空约束。
把外键字段加了唯一和非空约束,从而实现一对一。 - 第二种:使用主键
让其中一张表既是主键,又是外键。
(一对一也有主从关系,举例人和身份证)
- 第一种:使用外键约束,唯一约束。非空约束。
3、多表关系映射配置要遵循的步骤
(1)确定两张表之间的关系(找外键)
(2)在数据库中实现两张表之间的关系建立
(3)在实体类中描述出两个实体之间的关系
(4)在映射配置文件中建立两个实体和两张表之间的关系
4、一对多关系映射配置及操作
- 实例:客户和联系人
(1)确定两张表之间的关系(找外键)
一个客户可以包含多个联系人
多个联系人可以属于同一个客户
因此是一对多关系
(2)在数据库中实现两张表之间的关系建立
实现一对多关系:靠外键
客户表是主表,联系人表是从表
需要在联系人表中添加外键
(3)在实体类中描述出两个实体之间的关系
主表的实体类应该包含从表实体类的集合引用
从表的实体类应该包含主表实体类的对象引用
(4)在映射配置文件中建立两个实体和两张表之间的关系
<!-- 一对多关系映射:从表实体的映射配置
涉及的标签:many-to-one
作用:建立多对一的映射配置
属性:name:从表实体中引用主表实体对象引用名称
class:指定属性对应的实体类名称
column:指定从表中外键字段的名称
-->
<many-to-one name="customer" class="Customer" column="lkm_cust_id"></many-to-one>
<!-- 一对多关系映射:主表实体的映射配置
涉及的标签:set
作用:用于配置set集合属性
属性:name:指定实体类中set集合的属性名称
table:指从表的名称。在一对多配置时可以不写。
key:
作用:用于映射外键字段
属性:column:指定外键字段名称
one-to-many:
作用:用于建立一对多的映射配置
属性:class:用于指定从表实体类的名称
-->
<set name="LinkMan" table="cst_linkman">
<key column="lkm_cust_id"></key>
<one-to-many class="LinkMan"/>
</set>
注意:Hibernate在拼接SQL语句的时候需要用到外键信息,因此主表和从表都需要外键,并且名称一致。
1. 例子(代码):
/**
* 保存操作:创建一个新的联系人,需要关联一个客户
* */
@Test
public void Test1() {
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
//1.查询一个客户
Customer c1 = s.get(Customer.class, 1L);
//2.创建一个新的联系人
LinkMan l = new LinkMan();
l.setLkmName("一对多的联系人");
//3.建立客户和联系人的关联关系(让联系人知道属于哪个客户)
l.setCustomer(c1);
//4.保存联系人
s.save(l);
tx.commit();
}
/**
* 特殊情况:
* 创建一个联系人和一个客户
* 建立联系人和客户的双向关联关系
* 使用符合原则的保存会出现问题:
* 保存两个实体,本应该只有两条insert语句
* 而执行结果却是多了一条update语句
* */
@Test
public void Test2() {
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
//1.创建一个客户
Customer c1 = new Customer(); //瞬时态
c1.setCust_Name("一对多的客户");
//2.创建一个新的联系人
LinkMan l = new LinkMan(); //瞬时态
l.setLkmName("一对多的联系人");
//3.建立客户和联系人的关联关系(双向)
l.setCustomer(c1);
c1.getLinkmans().add(l);
//4.保存联系人,要符合原则
s.save(c1); //持久态,有一级缓存和快照
s.save(l); //持久态,有一级缓存和快照
tx.commit();
}
debug:
控制台:
2. 级联保存:
代码:
Save-update:可以级联保存,可以同时更新,也可以既保存又更新
3.删除
4.查询–对象导航查询
当实体之间有关联关系时(关联关系可以是4种中的任意一种)
Lazy(延迟加载)
5、多对多关系映射配置及操作
(1)确定两张表之间的关系(找外键)
一个用户可以有多个角色
一个角色可以赋给多个用户
因此是多对多关系
(2)在数据库中实现两张表之间的关系建立
在数据库中实现多对多要靠中间表
中间表只能出现用户和角色的主键
(3)在实体类中描述出两个实体之间的关系
(4)在映射配置文件中建立两个实体和两张表之间的关系
<set name="roles" table="user_role">
<key column="user_id"></key>
<many-to-many column="role_id" class="SysRole"></many-to-many>
</set>
联合主键的建立
多对多保存操作
多对多的删除操作
在实际开发中,多对多的双向级联删除是禁止使用的