Java繼承映射的三種使用方法示例
前言
在 Java 中,ORM(對(duì)象關(guān)系映射)框架(如 Hibernate/JPA)處理繼承關(guān)系時(shí),主要有三種繼承映射策略:單表繼承(Single Table)、連接表繼承(Joined Table) 和 每個(gè)具體類一張表(Table Per Class)。以下介紹它們的原理、使用方法和注意事項(xiàng)
博客將會(huì)介紹如何實(shí)現(xiàn) Java 三種繼承映射的使用。希望這篇博客對(duì)Unity的開發(fā)者有所幫助。
大家好,我是心疼你的一切,不定時(shí)更新Unity開發(fā)技巧,覺得有用記得一鍵三連哦。
歡迎點(diǎn)贊評(píng)論哦.下面就讓我們進(jìn)入正文吧 !
一、單表繼承(Single Table Inheritance)
1-1、原理
所有類共享一張表:整個(gè)繼承層次結(jié)構(gòu)的所有字段都存儲(chǔ)在同一張數(shù)據(jù)庫表中。
鑒別器列(Discriminator):使用一個(gè)特殊列(如 dtype)區(qū)分不同子類的記錄。
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):
查詢效率高(無 JOIN 操作)。
簡單易用。缺點(diǎn):
數(shù)據(jù)冗余:子類特有字段在非對(duì)應(yīng)記錄中為 NULL。
字段約束弱:非空約束(NOT NULL)無法用于子類特有字段(因?yàn)槠渌宇愑涗浿羞@些字段為 NULL)。適用場(chǎng)景:繼承層次簡單、子類字段差異小、查詢性能要求高的場(chǎng)景。
二、連接表繼承(Joined Table Inheritance)
2-1、原理
父類獨(dú)立表:父類字段存儲(chǔ)在基表中。
子類分表存儲(chǔ):子類特有字段存儲(chǔ)在獨(dú)立的子表中,通過主鍵與基表關(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ù)庫范式,無冗余字段。
支持子類字段的非空約束。 - 缺點(diǎn):
查詢需要 JOIN 操作,性能較低(尤其層次深時(shí))。
插入需操作多張表。 - 適用場(chǎng)景:數(shù)據(jù)結(jié)構(gòu)規(guī)范、子類字段差異大、對(duì)冗余敏感的場(chǎng)景。
三、每個(gè)具體類一張表(Table Per Class)
3-1、原理
每個(gè)具體類獨(dú)立成表:每個(gè)非抽象子類擁有一張獨(dú)立的表,表中包含自身字段 + 所有繼承的父類字段。
抽象父類無表:父類不映射到數(shù)據(jù)庫表(僅用于 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)如下:
-- 父類 Shape 無表 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):
查詢具體類時(shí)效率高(無需 JOIN)。
無冗余字段。缺點(diǎn):
多態(tài)查詢性能差:查詢父類(如 Shape)需 UNION 所有子表。
主鍵生成策略需用 TABLE 或 SEQUENCE(避免不同子表主鍵沖突)。適用場(chǎng)景:多態(tài)查詢少、主要操作具體子類的場(chǎng)景。
四、總結(jié)對(duì)比
策略 | 單表繼承(SINGLE_TABLE) | 連接表繼承(JOINED) | 每個(gè)具體類一張表(TABLE_PER_CLASS) |
---|---|---|---|
表數(shù)量 | 1 張 | N + 1 張(N=子類數(shù)) | N 張(N=具體子類數(shù)) |
數(shù)據(jù)冗余 | 高(大量 NULL) | 無 | 無 |
查詢性能 | ?????(無 JOIN) | ??(需 JOIN) | ???(具體類快,父類慢) |
字段約束 | 弱(不可用 NOT NULL) | 強(qiáng)(支持約束) | 強(qiáng)(支持約束) |
適用場(chǎng)景 | 簡單繼承、高性能需求 | 結(jié)構(gòu)規(guī)范、減少冗余 | 少用父類查詢、操作具體子類 |
通用注意事項(xiàng)
抽象父類:若父類是抽象的,使用 @MappedSuperclass 代替 @Entity(僅用于繼承字段,不映射表)。
鑒別器列:單表繼承必須用 @DiscriminatorColumn 和 @DiscriminatorValue。
多態(tài)查詢:連接表繼承和單表繼承對(duì)多態(tài)查詢支持較好。
主鍵策略:避免在 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)文章
JAVA導(dǎo)出EXCEL表格的實(shí)例教學(xué)
在本文中我們給大家整理了關(guān)于JAVA導(dǎo)出EXCEL表格的實(shí)例教學(xué)以及相關(guān)知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。2019-02-02SpringMVC Mybatis配置多個(gè)數(shù)據(jù)源并切換代碼詳解
這篇文章主要介紹了SpringMVC Mybatis配置多個(gè)數(shù)據(jù)源并切換代碼詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11Java實(shí)現(xiàn)解析JSON大文件JsonReader工具詳解
這篇文章主要介紹了Java實(shí)現(xiàn)解析JSON大文件的工具JsonReader使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-01-01Spring Cache @Cacheable 緩存在部分Service中不生效的解決辦法
這篇文章主要介紹了Spring Cache @Cacheable 緩存在部分Service中不生效的解決辦法2023-10-10java 基礎(chǔ)之JavaBean屬性命名規(guī)范問題
這篇文章主要介紹了java 基礎(chǔ)之JavaBean屬性命名規(guī)范問題的相關(guān)資料,需要的朋友可以參考下2017-05-05java異步調(diào)用的4種實(shí)現(xiàn)方法
日常開發(fā)中,會(huì)經(jīng)常遇到說,前臺(tái)調(diào)服務(wù),本文主要介紹了java異步調(diào)用的4種實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03