第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Hibernate 繼承映射

1. 前言

本節(jié)課程和大家一起學(xué)習(xí)繼承映射。通過本節(jié)課程的學(xué)習(xí),你將了解到:

  • 什么是繼承映射;
  • 實(shí)現(xiàn)繼承映射的 3 種方案。

2. 繼承映射

學(xué)習(xí)繼承映射之前,需要搞清楚什么是繼承映射?

繼承是 OOP 中的概念,其目的除了復(fù)用代碼之外,還用來描述對(duì)象在現(xiàn)實(shí)世界中的關(guān)系。

為了更好地講解繼承映射,咱們?cè)僭跀?shù)據(jù)庫中創(chuàng)建一張老師表。數(shù)據(jù)庫中多了一張表,按照使用 Hibernate 的套路,理所當(dāng)然應(yīng)該在程序中添加一個(gè)老師類。

@Entity
public class Teacher {
	private Integer teacherId;
	private String teacherName;
	private Integer serviceYear;
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public Integer getTeacherId() {
		return teacherId;
	}
   //省略其它……
}

OOP 的角度進(jìn)行分析,可以為學(xué)生類老師類創(chuàng)建一個(gè)共同的父類,描述兩者共同的屬性。

所以,你會(huì)看到如下 3 個(gè)類型:

public class Person implements Serializable {

}
public class Teacher extends Person implements Serializable {
}

public class Student extends Person implements Serializable {
}

程序中通過 OOP 繼承語法重新描述了學(xué)生類和老師類的關(guān)系,程序中結(jié)構(gòu)上的變化,必然會(huì)讓 Hibernate 茫然不知所措,因?yàn)殛P(guān)系型數(shù)據(jù)庫中是沒有繼承一說的。

此時(shí),就需要告訴 Hibernate 如何把程序中的繼承關(guān)系映射到數(shù)據(jù)庫中。

這就叫做繼承映射!

3. 繼承映射的實(shí)現(xiàn)

知道了什么是繼承映射,現(xiàn)在就到了怎么實(shí)現(xiàn)的環(huán)節(jié)。

先介紹大家認(rèn)識(shí)一下 @Inheritance 注解,識(shí)其名,知其意,繼承映射的實(shí)現(xiàn)就是靠它實(shí)現(xiàn)的。

并且它還提供了 3 種方案。

3 種方案各有自身的使用場(chǎng)景,如何選擇,根據(jù)實(shí)際情況定奪。

來!排好隊(duì),開始點(diǎn)名。

3.1 SINGLE_TABLE 策略

SINGLE_TABLE 策略: 數(shù)據(jù)庫中使用一張表結(jié)構(gòu)描述 OOP 中的繼承關(guān)系。

圖片描述

學(xué)生數(shù)據(jù)、老師數(shù)據(jù)以及其它工作人員的信息都放在一張表中??上攵@種映射的實(shí)用價(jià)值并不是很大,因?yàn)闆]有較好地遵循數(shù)據(jù)庫設(shè)計(jì)范式。

留一個(gè)問題給大家思考:數(shù)據(jù)庫設(shè)計(jì)范式有哪些?

既然大家都擠在一張表里,一想想,就覺得悶得慌。天呀,都在一起,怎么區(qū)分這張表中的數(shù)據(jù)誰是誰?

添加一個(gè)鑒別器字段!

所謂鑒別器字段,就是在表中添加了一個(gè)字段區(qū)分彼此之間的身份,這個(gè)字段充當(dāng)?shù)木褪氰b別器(discriminator)的功能。

表中的數(shù)據(jù)可能是這樣子:
圖片描述

不敢直視,有點(diǎn)像住混合宿舍,大通鋪的那種。

對(duì)于這種策略,建議用于數(shù)據(jù)關(guān)系不是很復(fù)雜的應(yīng)用場(chǎng)景下。

貼上關(guān)鍵的注解映射代碼:

Peson 類:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("person")
public class Person implements Serializable {
	//標(biāo)識(shí)
	private Integer id;
	//姓名
	private String name;
	//性別
	private String sex;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
   //省略其它……
}

細(xì)究一下上面用到的 2 個(gè)注解:

  • @Inheritance: 繼承映射注解,此注解有一個(gè)很重要的 strategy 屬性,strategy 屬性是一個(gè)枚舉類型,有 3 個(gè)可選值,也就是 3 種繼承映射 策略:
InheritanceType.SINGLE_TABLE 
InheritanceType.TABLE_PER_CLASS
InheritanceType.JOINED
  • @DiscriminatorColumn:
@DiscriminatorColumn(name = "discriminator",discriminatorType=DiscriminatorType.STRING)

此注解的作用就是添加一個(gè)冗余的識(shí)別字段,用來區(qū)分表中彼此的身份。

@DiscriminatorValue("person")

對(duì)于 Persono 類的信息區(qū)分關(guān)鍵字是 person。你可以指定任意的你覺得有意思的名字。

學(xué)生類中只需要出現(xiàn)僅屬于自己的屬性,再標(biāo)注自己的身份說明標(biāo)簽:

@Entity
@DiscriminatorValue("student")
public class Student extends Person implements Serializable {
	//最喜歡的課程
	private String loveCourse;
   //其它代碼……
}

老師類:

@Entity
@DiscriminatorValue("teacher")
public class Teacher extends Person{
	
	//工作年限
	private Integer serviceYear;
  //其它代碼……
}

修改主配置文件中的信息:

<property name="hbm2ddl.auto">create</property>
<mapping class="com.mk.po.inheritance.Person" />
<mapping class="com.mk.po.inheritance.Student" />
<mapping class="com.mk.po.inheritance.Teacher" />

測(cè)試下面的實(shí)例,僅僅只是為了創(chuàng)建新表,不用添加任何具體的操作代碼。

HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>();
		hibernateTemplate.template(new Notify<Student>() {
			@Override
			public Student action(Session session) {				
				return null;
			}
		});

進(jìn)入 MySql,查看表生成情況:
圖片描述
有且僅有一張表。

大功告成,這種映射策略不再細(xì)究,如果有興趣,添加、查詢數(shù)據(jù)等操作自己去玩。

3.2 TABLE_PER_CLASS 策略

TABLE_PER_CLASS: 每一個(gè)類對(duì)應(yīng)一張表,每一張表中保存自己的數(shù)據(jù)。

最后的數(shù)據(jù)保存方式如下:

圖片描述

貼出 3 個(gè)類中的注解信息:

Person 類:

@Entity 
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Person implements Serializable {
	//標(biāo)識(shí)
	private Integer id;
	//姓名
	private String name;
	//性別
	private String sex;
	@Id
	public Integer getId() {
		return id;
	}
//其它代碼……
}

Person 類中不再需要 鑒別器。這里有一個(gè)坑要引起注意, id 屬性上不要添加主鍵生成器相關(guān)的注解。

Student 類:

@Entity
public class Student extends Person implements Serializable {
	//最喜歡的課程
	private String loveCourse;
//其它信息
}

Teacher 類:

@Entity
public class Teacher extends Person{	
	//工作年限
	private Integer serviceYear;
    //其它代碼……
}

執(zhí)行測(cè)試實(shí)例,重新創(chuàng)建新表

HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>();
		hibernateTemplate.template(new Notify<Student>() {
			@Override
			public Student action(Session session) {
				return null;
			}
		});

直接進(jìn)入 MySql 查看一下表生成情況:
圖片描述

類、表結(jié)構(gòu)都有了,該干嘛去干嘛。

當(dāng)然,繼續(xù)下面內(nèi)容之前,評(píng)價(jià)一下這種策略。這種方式應(yīng)該是符合主流要求的,建議大家使用這種方式。

3.3 JOINED 策略

JOINED: 將父類、子類分別存放在不同的表中,并且建立相應(yīng)的外鍵,以確定相互之間的關(guān)系。

將來的數(shù)據(jù)應(yīng)該和下面一樣:

圖片描述

第三種策略的映射代碼和第二種策略唯一不同的地方,就在 person 中的策略改成了:

@Inheritance(strategy=InheritanceType.JOINED)

好吧,跑一下測(cè)試實(shí)例:

HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>();
		hibernateTemplate.template(new Notify<Student>() {
			@Override
			public Student action(Session session) {
		    return null;
			}
		});

進(jìn)入 MySql 查看生成的表結(jié)構(gòu):
圖片描述
這種策略從表內(nèi)容來講,會(huì)把學(xué)生和老師共同的字段信息保存到一張表中,兩個(gè)子表只分別保存屬于自己的信息。

JOINED 策略從使用角度上講增加了查詢時(shí)間,對(duì)學(xué)生、老師信息進(jìn)行保存和查詢操作時(shí)需要連接 person 表,顯然增加了操作時(shí)間。

并且,表中的數(shù)據(jù)不完善,有點(diǎn)殘缺不全的感覺。

相信各自還是有自己的優(yōu)缺點(diǎn):

  • SINGLE_TABLE: 除了速度杠桿的,但不分你我,數(shù)據(jù)擠在一起,只怕數(shù)據(jù)多了,遲早會(huì)出現(xiàn)異常;
  • TABLE_PER_CLASS: 類結(jié)構(gòu)符合 OOP 標(biāo)準(zhǔn),表結(jié)構(gòu)符合關(guān)系型數(shù)據(jù)庫范式。數(shù)據(jù)之間分界線清晰,操作速度也還可以;
  • JOINED:SINGLE_TABLE 有點(diǎn)類似,原來是全部擠在一起。為了緩解空間,一部分?jǐn)?shù)據(jù)擠在一起,另一部分放在自己的表中,速度不會(huì)提升,數(shù)據(jù)表完整性得不到保存。

客觀上對(duì) 3 種策略進(jìn)行縱橫比較,最后選擇使用哪一種策略,還是由項(xiàng)目需求決定吧。

存在,就有合理性。

4. 小結(jié)

本節(jié)課講解了繼承映射,學(xué)習(xí)了 3 種繼續(xù)映射的實(shí)現(xiàn)。

3 種策略肯定有自己的應(yīng)用場(chǎng)景,也會(huì)有不同的追求者。本節(jié)課從客觀上對(duì)三策略做了一個(gè)評(píng)估,選擇誰由項(xiàng)目需求來決定。