对象关系.
- 泛化
- 实现
- 依赖
- 关联:
- 单向 一对一
- 单向 多对一
- 单向 一对多
- 单向 多对多
- 聚合
- 组合
一、泛化关系(generalization).
就是继承关系 (类和类之间–单继承,接口和接口之间–多继承) 关键字 :
extends
UML中,使用空心三角和实线表示
数据表的设计.
//普通用户
class User{
protected int id;//用户id
protected String name;//用户名
}
//vip用户
class VIPUser extends User{
private String point;//会员积分
}
//Super用户
class SuperUser extends User{
private String earning;//收益
}
1.共用一张表.
- 需要添加一列作为鉴别器,区分不同的类型
- 不能给一些字段做约束,如非空约束
- 查询效率最高
id | name | point | earning | type |
---|---|---|---|---|
1 | admin | null | 1 | 2 |
2 | 小王 | 100 | null | 1 |
3 | 老王 | null | null | 0 |
4 | 大漂亮 | 1000 | null | 1 |
2.每个子类一张表.
- 把子类共同字段数据,存在User表内
- 子类只存自己独有的字段数据
- 查询所有信息:横向查询(
join
通过外键关联)
User
id | name |
---|---|
1 | admin |
2 | 小王 |
3 | 老王 |
4 | 大漂亮 |
SuperUser
id(外键) | earning |
---|---|
1 | 1 |
VIPUser
id(外键) | point |
---|---|
2 | 100 |
4 | 1000 |
3.每个类一张表.
- 查询所有信息:纵向查询(
union
要保证各表间主键不能存在相同的)
User
id | name |
---|---|
1 | 老王 |
SuperUser
id | name | earning |
---|---|---|
2 | admin | 1 |
VIPUser
id | name | point |
---|---|---|
3 | 小王 | 100 |
4 | 大漂亮 | 1000 |
二、实现关系(realizaton).
类和接口之间 关键字 :
implements
UML中,使用空心三角和虚线表示
三、依赖关系(dependent).
有两个类,A类,B类;对象 : 类实例化
A对象依赖B对象的定义(即A类中使用B)
A对象没了B对象,就无法通过编译
UML中,使用虚线和箭头表示
public B{
}
public A{
public B b; // 1 使用到了B
public void test(B b/*2. 使用到了B*/){
B b; // 3 使用到了B
}
}
四、关联关系(association).
是一种特殊的依赖关系
A依赖于B,并且把B作为A的一个成员变量,那么A与B存在关联关系
UML中,使用实线和箭头表示
按多重性
- 一对一,一个A对象属于一个B对象,一个B对象属于一个A对象
- 一对多,一个A对象包含多个B对象
- 多对一,多个A对象属于一个B对象,且每个A对象只能属于一个B对象
- 多对多,一个A对象属于多个B对象,一个B对象属于多个A对象
按导航性
- 单向:只能通过A对象中的某一个属性可以访问到B对象,则A可以导航到B
- 双向:A可以通过属性导航到B,B也可以通过属性导航的A
数据表设计.
1.一对一.
- 共享主键
qqZone
id(与num的id对应) | address |
---|---|
1 | addr1 |
2 | addr2 |
qqNumber
id | number |
---|---|
1 | 111111 |
2 | 222222 |
- 外键(推荐:外键在哪个表都可以,看实际情况)
qqZone
id | address | number_id(外键) |
---|---|---|
1 | addr1 | 10 |
2 | addr2 | 20 |
qqNumber
id | number |
---|---|
10 | 111111 |
20 | 222222 |
2.一对多,多对一.
- 先保存少的一方,即先存入数据到父表(只有主键的表,子表依赖父表),再存子表(含有主键和外键的表)
student学生
id | name | cls_id |
---|---|---|
1 | 张三 | 2 |
2 | 李四 | 1 |
3 | 王五 | 2 |
class班级
id | name |
---|---|
1 | 1班 |
2 | 2班 |
3.多对多.
student
id | name |
---|---|
1 | 小明 |
2 | 小红 |
teacher
id | name |
---|---|
1 | 老师1 |
2 | 老师2 |
student_teacher(中间表)(联合主键:sid和tid )
sid(外键) | tid(外键) |
---|---|
1 | 2 |
2 | 1 |
2 | 2 |
五、聚合关系(aggregation).
一种 “ 弱拥有 ” 关系,表示为has-a
也是一种依赖
整体与个体之间可以相互独立存在,一定是有两个模块分别管理整体和个体
如果A和B是聚合关系,他们并不是一个独立的整体,A和 B的生命周期是不同的,通常一方会做为另一方的局部变量存在
UML中,使用空心菱形和实线表示
六、组合关系(composition).
一种强聚合关系,“ 强拥有 ”,表示为contains-a
也是一种依赖
整体和个体不能独立存在,一定是在一个模块中同时管理整体和个体,生命周期必须相同(级联)
级联(cascade):把主对象的操作遍历的在每一个从对象上面执行相同的操作(主表中关键字被修改或者删除,那么从表对应的关键字相同的记录也会被修改或删除)
UML中,使用实心菱形和实线表示
小结.
泛化和实现,主要体现 类和类、接口和接口 间的纵向关系
其他四种,体现 类与类,或者 类与接口间的引用、横向关系,语义级别(从代码层次,无法完全区分各种关系)
后4种强弱程度:组合 > 聚合 > 关联 > 依赖
在面向对象中,能使用强度大的,就不要使用强度小的
为什么多对多一定要一个中间表
- 如果两表多对多关联,就会产生笛卡尔积,这时两表都是大表,那效率就特别低。有可能睡一觉回来都没跑完。
- 可以通过中间表拆成两个一对多
一个 多对多关系 可以转换成两个 一对多关系
下面举例说明:
有 学生表 与 选修课程表 多对多关系
一个学生可以选择多门课程, 一门课程可以被多个学生选修.
需要新增加一个 学生选修课程情况表,2个字段(学生编号, 课程编号)
然后
学生表 与 学生选修课程情况表 为 一对多关系.
选修课程表 与 学生选修课程情况表 为 一对多关系.