Java繼承映射的三種使用方法示例
前言
在 Java 中,ORM(對(duì)象關(guān)系映射)框架(如 Hibernate/JPA)處理繼承關(guān)系時(shí),主要有三種繼承映射策略:?jiǎn)伪砝^承(Single Table)、連接表繼承(Joined Table) 和 每個(gè)具體類(lèi)一張表(Table Per Class)。以下介紹它們的原理、使用方法和注意事項(xiàng)
博客將會(huì)介紹如何實(shí)現(xiàn) Java 三種繼承映射的使用。希望這篇博客對(duì)Unity的開(kāi)發(fā)者有所幫助。
大家好,我是心疼你的一切,不定時(shí)更新Unity開(kāi)發(fā)技巧,覺(jué)得有用記得一鍵三連哦。
歡迎點(diǎn)贊評(píng)論哦.下面就讓我們進(jìn)入正文吧 !
一、單表繼承(Single Table Inheritance)
1-1、原理
所有類(lèi)共享一張表:整個(gè)繼承層次結(jié)構(gòu)的所有字段都存儲(chǔ)在同一張數(shù)據(jù)庫(kù)表中。
鑒別器列(Discriminator):使用一個(gè)特殊列(如 dtype)區(qū)分不同子類(lèi)的記錄。
1-2、使用方法
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 指定策略
@DiscriminatorColumn(name = "dtype") // 鑒別器列名
public class Animal {
@Id
private Long id;
private String name;
}
@Entity
@DiscriminatorValue("CAT") // 鑒別器值
public class Cat extends Animal {
private int lives;
}
@Entity
@DiscriminatorValue("DOG")
public class Dog extends Animal {
private boolean canFetch;
}
表結(jié)構(gòu)如下:
CREATE TABLE Animal (
id BIGINT PRIMARY KEY,
name VARCHAR(255),
lives INTEGER, -- Cat 的字段
canFetch BOOLEAN, -- Dog 的字段
dtype VARCHAR(10) -- 鑒別器列(值如 "CAT"/"DOG")
);
1-3、注意事項(xiàng)
優(yōu)點(diǎn):
查詢(xún)效率高(無(wú) JOIN 操作)。
簡(jiǎn)單易用。缺點(diǎn):
數(shù)據(jù)冗余:子類(lèi)特有字段在非對(duì)應(yīng)記錄中為 NULL。
字段約束弱:非空約束(NOT NULL)無(wú)法用于子類(lèi)特有字段(因?yàn)槠渌宇?lèi)記錄中這些字段為 NULL)。適用場(chǎng)景:繼承層次簡(jiǎn)單、子類(lèi)字段差異小、查詢(xún)性能要求高的場(chǎng)景。
二、連接表繼承(Joined Table Inheritance)
2-1、原理
父類(lèi)獨(dú)立表:父類(lèi)字段存儲(chǔ)在基表中。
子類(lèi)分表存儲(chǔ):子類(lèi)特有字段存儲(chǔ)在獨(dú)立的子表中,通過(guò)主鍵與基表關(guān)聯(lián)(一對(duì)一關(guān)系)。
2-2、使用方法
@Entity
@Inheritance(strategy = InheritanceType.JOINED) // 指定策略
public class Vehicle {
@Id
private Long id;
private String manufacturer;
}
@Entity
public class Car extends Vehicle {
private int seatCount;
}
@Entity
public class Truck extends Vehicle {
private double payloadCapacity;
}
生成的表結(jié)構(gòu)如下:
-- 基表(存儲(chǔ)公共字段)
CREATE TABLE Vehicle (
id BIGINT PRIMARY KEY,
manufacturer VARCHAR(255)
);
-- 子表(存儲(chǔ)特有字段 + 關(guān)聯(lián)基表主鍵)
CREATE TABLE Car (
id BIGINT PRIMARY KEY, -- 與 Vehicle.id 相同
seatCount INTEGER,
FOREIGN KEY (id) REFERENCES Vehicle(id)
);
CREATE TABLE Truck (
id BIGINT PRIMARY KEY,
payloadCapacity DOUBLE,
FOREIGN KEY (id) REFERENCES Vehicle(id)
);
2-3、注意事項(xiàng)
- 優(yōu)點(diǎn):
符合數(shù)據(jù)庫(kù)范式,無(wú)冗余字段。
支持子類(lèi)字段的非空約束。 - 缺點(diǎn):
查詢(xún)需要 JOIN 操作,性能較低(尤其層次深時(shí))。
插入需操作多張表。 - 適用場(chǎng)景:數(shù)據(jù)結(jié)構(gòu)規(guī)范、子類(lèi)字段差異大、對(duì)冗余敏感的場(chǎng)景。
三、每個(gè)具體類(lèi)一張表(Table Per Class)
3-1、原理
每個(gè)具體類(lèi)獨(dú)立成表:每個(gè)非抽象子類(lèi)擁有一張獨(dú)立的表,表中包含自身字段 + 所有繼承的父類(lèi)字段。
抽象父類(lèi)無(wú)表:父類(lèi)不映射到數(shù)據(jù)庫(kù)表(僅用于 Java 繼承)。
3-2、使用方法
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) // 指定策略
public abstract class Shape {
@Id
private Long id;
private String color;
}
@Entity
public class Circle extends Shape {
private double radius;
}
@Entity
public class Rectangle extends Shape {
private double width;
private double height;
}
生成的表結(jié)構(gòu)如下:
-- 父類(lèi) Shape 無(wú)表
CREATE TABLE Circle (
id BIGINT PRIMARY KEY,
color VARCHAR(255), -- 繼承自 Shape
radius DOUBLE
);
CREATE TABLE Rectangle (
id BIGINT PRIMARY KEY,
color VARCHAR(255), -- 繼承自 Shape
width DOUBLE,
height DOUBLE
);
3-3、注意事項(xiàng)
優(yōu)點(diǎn):
查詢(xún)具體類(lèi)時(shí)效率高(無(wú)需 JOIN)。
無(wú)冗余字段。缺點(diǎn):
多態(tài)查詢(xún)性能差:查詢(xún)父類(lèi)(如 Shape)需 UNION 所有子表。
主鍵生成策略需用 TABLE 或 SEQUENCE(避免不同子表主鍵沖突)。適用場(chǎng)景:多態(tài)查詢(xún)少、主要操作具體子類(lèi)的場(chǎng)景。
四、總結(jié)對(duì)比
| 策略 | 單表繼承(SINGLE_TABLE) | 連接表繼承(JOINED) | 每個(gè)具體類(lèi)一張表(TABLE_PER_CLASS) |
|---|---|---|---|
| 表數(shù)量 | 1 張 | N + 1 張(N=子類(lèi)數(shù)) | N 張(N=具體子類(lèi)數(shù)) |
| 數(shù)據(jù)冗余 | 高(大量 NULL) | 無(wú) | 無(wú) |
| 查詢(xún)性能 | ?????(無(wú) JOIN) | ??(需 JOIN) | ???(具體類(lèi)快,父類(lèi)慢) |
| 字段約束 | 弱(不可用 NOT NULL) | 強(qiáng)(支持約束) | 強(qiáng)(支持約束) |
| 適用場(chǎng)景 | 簡(jiǎn)單繼承、高性能需求 | 結(jié)構(gòu)規(guī)范、減少冗余 | 少用父類(lèi)查詢(xún)、操作具體子類(lèi) |
通用注意事項(xiàng)
抽象父類(lèi):若父類(lèi)是抽象的,使用 @MappedSuperclass 代替 @Entity(僅用于繼承字段,不映射表)。
鑒別器列:?jiǎn)伪砝^承必須用 @DiscriminatorColumn 和 @DiscriminatorValue。
多態(tài)查詢(xún):連接表繼承和單表繼承對(duì)多態(tài)查詢(xún)支持較好。
主鍵策略:避免在 TABLE_PER_CLASS 中使用 IDENTITY 主鍵生成(不同表主鍵可能沖突)。
總結(jié)
本次總結(jié)的就是 Java 三種繼承映射的使用實(shí)現(xiàn), 有需要會(huì)繼續(xù)增加功能
到此這篇關(guān)于Java繼承映射的三種使用方法的文章就介紹到這了,更多相關(guān)Java繼承映射使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Springboot打成JAR包后讀取外部配置文件的問(wèn)題
這篇文章主要介紹了關(guān)于Springboot打成JAR包后讀取外部配置文件的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
Java內(nèi)存模型之happens-before概念詳解
happens-before原則非常重要,它是判斷數(shù)據(jù)是否存在競(jìng)爭(zhēng)、線程是否安全的主要依據(jù),依靠這個(gè)原則,我們解決在并發(fā)環(huán)境下兩操作之間是否可能存在沖突的所有問(wèn)題。下面我們就一個(gè)簡(jiǎn)單的例子稍微了解下happens-before知識(shí),感興趣的朋友一起看看吧2021-06-06
Maven打包編譯出現(xiàn)Fileencodinghasnotbeenset問(wèn)題的解決方案
在使用Maven進(jìn)行項(xiàng)目構(gòu)建時(shí),有時(shí)會(huì)遇到??File encoding has not been set??的錯(cuò)誤提示,這個(gè)問(wèn)題通常出現(xiàn)在Maven嘗試編譯Java源文件時(shí),本文將詳細(xì)介紹該問(wèn)題的原因、解決方法以及如何避免類(lèi)似問(wèn)題再次發(fā)生,需要的朋友可以參考下2025-11-11
淺談MyBatis 如何執(zhí)行一條 SQL語(yǔ)句
Mybatis 是 Java 開(kāi)發(fā)中比較常用的 ORM 框架。在日常工作中,我們都是直接通過(guò) Spring Boot 自動(dòng)配置,并直接使用,但是卻不知道 Mybatis 是如何執(zhí)行一條 SQL 語(yǔ)句的,下面就一起講解一下2021-05-05
SpringBoot @PropertySource與@ImportResource有什么區(qū)別
這篇文章主要介紹了SpringBoot @PropertySource與@ImportResource有什么區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2023-01-01
用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的布隆過(guò)濾器
這篇文章主要介紹了用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的布隆過(guò)濾器,布隆過(guò)濾器是1970年由布隆提出的,它實(shí)際上是一個(gè)很長(zhǎng)的二進(jìn)制向量和一系列隨機(jī)映射函數(shù),布隆過(guò)濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中,需要的朋友可以參考下2023-12-12
SpringBoot項(xiàng)目使用Log4j2+SLF4J構(gòu)建日志的方法步驟
在現(xiàn)代軟件開(kāi)發(fā)中,日志記錄是一個(gè)重要的部分,Spring Boot配置了多種日志框架,這篇文章主要介紹了SpringBoot項(xiàng)目使用Log4j2+SLF4J構(gòu)建日志的方法步驟,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-11-11
詳解Spring ApplicationContext加載過(guò)程
這篇文章主要介紹了Spring ApplicationContext加載過(guò)程的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用spring框架,感興趣的朋友可以了解下2021-03-03
Jmeter中的timeshift()函數(shù)獲取當(dāng)前時(shí)間進(jìn)行加減
這篇文章主要介紹了Jmeter中的timeshift()函數(shù)獲取當(dāng)前時(shí)間進(jìn)行加減,TimeShift(格式,日期,移位,語(yǔ)言環(huán)境,變量)可對(duì)日期進(jìn)行移位加減操作,本文給大家詳細(xì)講解,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
如何發(fā)布jar包到maven中央倉(cāng)庫(kù)
這篇文章主要介紹了發(fā)布jar包到maven中央倉(cāng)庫(kù)的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-12-12

