CUBA 框架实体继承策略探究
一 项目准备
新建项目, 起名 inherit
在 global 层建好 A, B, C 三个实体, 其中 B 和 C 继承 A, 如下:
A.kt
@Table(name = "INHERIT_A")
@Entity(name = "inherit_A")
open class A : StandardEntity() {
companion object {
private const val serialVersionUID = 2490051969193359463L
}
@Column(name = "A_VALUE")
var aValue: Int? = null
}
B.kt
@Table(name = "INHERIT_B")
@Entity(name = "inherit_B")
open class B : A() {
companion object {
private const val serialVersionUID = 8001568716900684160L
}
@Column(name = "B_VALUE")
var bValue: Int? = null
}
C.kt
@Table(name = "INHERIT_C")
@Entity(name = "inherit_C")
open class C : A() {
companion object {
private const val serialVersionUID = 4481159091960932193L
}
@Column(name = "C_VALUE")
var cValue: Int? = null
}
cuba 的继承策略默认在父类上定义, 如果不显式定义的话默认是单表策略
二 简单继承关系探究
1. SINGLE_TABLE
上述实体建立后创建表的话默认就是 SINGLE_TABLE
策略, 生成的 DDL 如下:
-- begin INHERIT_A
create table INHERIT_A (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
DTYPE varchar(31),
--
A_VALUE integer,
--
-- from inherit_C
C_VALUE integer,
--
-- from inherit_B
B_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_A
显式指定单表策略只需要在 A 类上加 @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
生成的 DDL 是一样的
很显然, 结论是:
- 三个实体只会存到同一张表中
- 如果主键使用的是自增 ID, 将会出现单个类型的实体的 ID 不连续的问题
2. JOINED
JOINED
策略只需要在 A 类上添加 @Inheritance(strategy = InheritanceType.JOINED)
此策略生成的 DDL 如下
-- begin INHERIT_A
create table INHERIT_A (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
DTYPE varchar(31),
--
A_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_A
-- begin INHERIT_B
create table INHERIT_B (
ID varchar(32),
--
B_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_B
-- begin INHERIT_C
create table INHERIT_C (
ID varchar(32),
--
C_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_C
建好 A, B, C 三个实体的 Browser 与 Editor 页面, 并三者分别添加一条记录
查看数据库如下:
A 实体页面:
可得结论: JOINED 策略中:
- 三个实体分别存到三个表中, 其中公共的属性存在父实体表中, 特有属性存在自己表中
- 父实体与子实体的表之间通过主键关联
- 对子实体的查询其实是通过 父 JOIN 子 的形式查出完整数据
- 同样会出现同单个类型的实体的 ID 不连续的问题
3. TABLE_PER_CLASS
TABLE_PER_CLASS
策略只需要在 A 类上添加 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
生成的 DDL 如下:
-- begin INHERIT_A
create table INHERIT_A (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
--
A_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_A
-- begin INHERIT_B
create table INHERIT_B (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
A_VALUE integer,
--
B_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_B
-- begin INHERIT_C
create table INHERIT_C (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
A_VALUE integer,
--
C_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_C
如同名字一样, 此策略对每个实体单独创建一张完整数据的表
同样在页面上对每个实体都新增一条记录, 数据库结果:
A 实体页面:
可见页面上还是能体现出实体间的父子关系, 而在数据库表中三者间的数据已经互不耦合了
TABLE_PER_CLASS
结论如下:
- 三个实体的完整数据分别存到三个独立完整的表中
- 父实体与子实体的表之间无关联
- 对子实体的查询是独立的
- 不会出现同单个类型的实体的 ID 不连续的问题
复合继承关系探究
1. 普通复合关系
如果是如下关系, 那 CUBA 将会如何生成 DDL 呢
生成的 DDL 如下:
-- begin INHERIT_A
create table INHERIT_A (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
--
A_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_A
-- begin INHERIT_B
create table INHERIT_B (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
A_VALUE integer,
--
B_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_B
-- begin INHERIT_C
create table INHERIT_C (
ID varchar(32),
--
C_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_C
-- begin INHERIT_E
create table INHERIT_E (
ID varchar(32),
--
E_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_E
-- begin INHERIT_D
create table INHERIT_D (
ID varchar(32),
--
D_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_D
然而在启动项目的时候报错了:
2. 隔代复合关系
如果是如下关系又会怎么样呢
生成的 DDL 如下:
-- begin INHERIT_A
create table INHERIT_A (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
--
A_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_A
-- begin INHERIT_B
create table INHERIT_B (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
A_VALUE integer,
--
B_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_B
-- begin INHERIT_C
create table INHERIT_C (
ID varchar(32),
--
C_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_C
-- begin INHERIT_E
create table INHERIT_E (
ID varchar(32),
--
E_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_E
-- begin INHERIT_D
create table INHERIT_D (
ID varchar(32),
VERSION integer not null,
CREATE_TS datetime(3),
CREATED_BY varchar(50),
UPDATE_TS datetime(3),
UPDATED_BY varchar(50),
DELETE_TS datetime(3),
DELETED_BY varchar(50),
A_VALUE integer,
C_VALUE integer,
--
D_VALUE integer,
--
primary key (ID)
)^
-- end INHERIT_D
同样, 启动报错了, 继续研究也没有太大意义了
结论: CUBA 的实体继承策略不可复合
评论
其他文章