文章目錄
  1. 1. 设计思想
  2. 2. 每个类层次结构使用一个表
    1. 2.1. 域模型
    2. 2.2. 父类
    3. 2.3. BankAccount子类
    4. 2.4. CreditCard子类
    5. 2.5. 表的结构
  3. 3. SQL查询
    1. 3.1. hql
    2. 3.2. sql
  4. 4. Download ZIP

在学软件工程的时候没有弄明白ER图域模型的关系。后来才渐渐理解了。ER图是基于数据库的数据建模,是面向关系的,是has a的关系(类的组合),而域模型是面向对象的,既是has a又是is a的关系(类的继承)。弄明白了这些之后我们知道在面向关系和对象的世界里继承是一种结构上的不匹配。但是我们如何才能完成继承关系在数据库中的映射呢?

设计思想

首先来介绍一下我们在思想上如何实现呢?

  • 每个子类使用一个表:将is a(继承)关系表示为has a(外键)关系,并且使用 SQL JOIN操作。
  • 每个类层次结构使用一个表。

每个类层次结构使用一个表

我们说这种方法是最简单的映射关系了。在这个类层次映射的到的数据表中乎有一个额外的类型识别器或公式的值会标识出特定行所表示的具体子类。

域模型

父类

1
2
3
4
5
6
7
8
9
10
11
12
13
@Entity
@DiscriminatorColumn(name = "table_type") //区分子类的标识符
public class BillingDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
@Column(nullable = false)
private String owner;
//getter and setter
}

BankAccount子类

1
2
3
4
5
6
7
8
@Entity
@DiscriminatorValue("CreditCard") //table_type字段为CreditCard时表示CreditCard类
public class CreditCard extends BillingDetails {
protected String cardNumber;
protected String expMonth;
//gettter and setter
}

CreditCard子类

1
2
3
4
5
6
7
8
@Entity
@DiscriminatorValue("CreditCard")
public class CreditCard extends BillingDetails {
protected String account;
protected String bankName;
//getter and setter
}

表的结构

SQL查询

BankAccount为例

hql

当我们用hql查询的时候没有什么改动,因为Hinernate已经为我们自动处理table_type这个字段来标示不同的子类。

1
select bankAccount from BankAccount as bankAccount

sql

1
2
3
4
5
6
select
ID, OWNER, CARDNUMBER, EXPMONTH
from
BILLINGDETAILS
where
TABLE_TYPE='BANKACCOUNT'

Download ZIP

文章目錄
  1. 1. 设计思想
  2. 2. 每个类层次结构使用一个表
    1. 2.1. 域模型
    2. 2.2. 父类
    3. 2.3. BankAccount子类
    4. 2.4. CreditCard子类
    5. 2.5. 表的结构
  3. 3. SQL查询
    1. 3.1. hql
    2. 3.2. sql
  4. 4. Download ZIP