溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

(14)Hibernate繼承映射

發(fā)布時間:2020-07-14 08:15:39 來源:網(wǎng)絡(luò) 閱讀:331 作者:lsieun 欄目:數(shù)據(jù)庫


人們總是在失去時,才了解到事情的本質(zhì)


需求:動物、貓、猴子

1、簡單繼承映射


Animal.java

package com.rk.hibernate.n_inheritance1;

public abstract class Animal
{
	private int id;
	private String name;
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	
}

Cat.java

package com.rk.hibernate.n_inheritance1;

public class Cat extends Animal
{
	private String catchMouse;

	public String getCatchMouse()
	{
		return catchMouse;
	}

	public void setCatchMouse(String catchMouse)
	{
		this.catchMouse = catchMouse;
	}

	@Override
	public String toString()
	{
		return "Cat [id=" + getId() + ", name=" + getName() + ", catchMouse=" + catchMouse + "]";
	}
	
}

Cat.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.n_inheritance1" auto-import="true">
	<class name="Cat" table="T_Cat">
		<!-- 簡單繼承映射: 父類屬性直接寫 -->
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name"></property>
		<property name="catchMouse" column="catchMouse"></property>
	</class>
</hibernate-mapping>

App.java

package com.rk.hibernate.n_inheritance1;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class App
{
	private static SessionFactory sf;
	static
	{
		sf = new Configuration()
						.configure()
						.addClass(Cat.class)
						.buildSessionFactory();
	}
	
	@Test
	public void testSave()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
		//貓
		Cat cat = new Cat();
		cat.setName("大花貓");
		cat.setCatchMouse("抓小老鼠");
		
		//保存
		session.save(cat);
		
		session.getTransaction().commit();
		session.close();
	}
	
	@Test
	public void testGetCat()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
		//通過HQL查詢Cat
		Query q = session.createQuery("from Cat");
		List<Cat> list = q.list();
		
		System.out.println(list);
		
		session.getTransaction().commit();
		session.close();
	}
	
	@Test
	public void testGetAnimal()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
		// 獲取時候注意:當(dāng)寫hql查詢的使用,通過父類查詢必須寫上類的全名
		Query q = session.createQuery("from com.rk.hibernate.n_inheritance1.Animal");
		List<Cat> list = q.list();
		
		System.out.println(list);
		
		session.getTransaction().commit();
		session.close();
	}
}

生成的T_Cat表

(14)Hibernate繼承映射



總結(jié):簡單繼承映射,有多少個子類,寫多少個映射文件!

2、繼承映射


下面3種方法都是只使用一個映射文件(Animal.hbm.xml文件),但是不同的方法生成的數(shù)據(jù)庫表的數(shù)量不同。

2.1、所有子類映射到同一張表(1張表)


什么情況用?

子類教多,且子類較為簡單,即只有個別屬性!

好處:因為使用一個映射文件, 減少了映射文件的個數(shù)。

缺點:(不符合數(shù)據(jù)庫設(shè)計原則)


Animal.java

package com.rk.hibernate.n_inheritance2;

public abstract class Animal
{
	private int id;
	private String name;
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	
}

Cat.java

package com.rk.hibernate.n_inheritance2;

public class Cat extends Animal
{
	private String catchMouse;

	public String getCatchMouse()
	{
		return catchMouse;
	}

	public void setCatchMouse(String catchMouse)
	{
		this.catchMouse = catchMouse;
	}

	@Override
	public String toString()
	{
		return "Cat [id=" + getId() + ", name=" + getName() + ", catchMouse=" + catchMouse + "]";
	}
	
}

Monkey.java

package com.rk.hibernate.n_inheritance2;

public class Monkey extends Animal
{
	private String eatBanana;

	public String getEatBanana()
	{
		return eatBanana;
	}

	public void setEatBanana(String eatBanana)
	{
		this.eatBanana = eatBanana;
	}
	
}

Animal.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- 
	繼承映射, 所有的子類都映射到一張表
 -->
<hibernate-mapping package="com.rk.hibernate.n_inheritance2" auto-import="true">
	<class name="Animal" table="T_Animals">
		<!-- 簡單繼承映射: 父類屬性直接寫 -->
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<!-- 指定鑒別器字段(區(qū)分不同的子類) -->
		<discriminator column="animal_Type"></discriminator>
		
		<property name="name" column="name"></property>

		<!-- 
			子類:貓
				每個子類都用subclass節(jié)點映射
				注意:一定要指定鑒別器字段,否則報錯!
				鑒別器字段:作用是在數(shù)據(jù)庫中區(qū)別每一個子類的信息, 就是一個列(column)
			discriminator-value="cat"
				指定鑒別器字段,即animal_Type字段的值
				如果不指定,默認(rèn)為當(dāng)前子類的全名
		 -->		
		<subclass name="Cat" discriminator-value="cat">
			<property name="catchMouse" column="catchMouse"></property>
		</subclass>
	
		 <!-- 
		 	子類:猴子
		  -->		
		<subclass name="Monkey" discriminator-value="monkey">
			<property name="eatBanana" column="eatBanana"></property>
		</subclass>
	</class>
</hibernate-mapping>

App.java

package com.rk.hibernate.n_inheritance2;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;


public class App
{
	private static SessionFactory sf;
	static
	{
		sf = new Configuration()
						.configure()
						.addClass(Animal.class)
						.buildSessionFactory();
	}
	
	@Test
	public void testSave()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
		//貓
		Cat cat = new Cat();
		cat.setName("大花貓");
		cat.setCatchMouse("抓小老鼠");
		
		//猴子
		Monkey monkey = new Monkey();
		monkey.setName("淘氣猴");
		monkey.setEatBanana("吃黃香蕉");
		
		//保存
		session.save(cat);
		session.save(monkey);
		
		session.getTransaction().commit();
		session.close();
	}
	
}

生成的T_Animals表

(14)Hibernate繼承映射


總結(jié):寫法較為簡單:所有子類用一個映射文件,且映射到一張表!但數(shù)據(jù)庫設(shè)計不合理!不推薦用。





2.2、每個類映射一張表(3張表)


Animal.java

package com.rk.hibernate.n_inheritance3;

public abstract class Animal
{
	private int id;
	private String name;
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	
}

Cat.java

package com.rk.hibernate.n_inheritance3;

public class Cat extends Animal
{
	private String catchMouse;

	public String getCatchMouse()
	{
		return catchMouse;
	}

	public void setCatchMouse(String catchMouse)
	{
		this.catchMouse = catchMouse;
	}

	@Override
	public String toString()
	{
		return "Cat [id=" + getId() + ", name=" + getName() + ", catchMouse=" + catchMouse + "]";
	}
	
}

Monkey.java

package com.rk.hibernate.n_inheritance3;

public class Monkey extends Animal
{
	private String eatBanana;

	public String getEatBanana()
	{
		return eatBanana;
	}

	public void setEatBanana(String eatBanana)
	{
		this.eatBanana = eatBanana;
	}
	
}

Animal.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- 
	繼承映射, 每個類對應(yīng)一張表(父類也對應(yīng)表)
 -->
<hibernate-mapping package="com.rk.hibernate.n_inheritance3" auto-import="true">
	<class name="Animal" table="T_Animal_Each">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name"></property>

		<!-- 
			子類:貓  t_cat
			key 指定_cat表的外鍵字段
		-->		
		<joined-subclass name="Cat" table="T_Cat_Each">
			<key column="animal_Id"></key>
			<property name="catchMouse" column="catchMouse"></property>
		</joined-subclass>
	
		<!-- 子類:猴子  t_monkey -->
		<joined-subclass name="Monkey" table="T_Monkey_Each">
			<key column="animal_Id"></key>
			<property name="eatBanana" column="eatBanana"></property>
		</joined-subclass>
	</class>
</hibernate-mapping>	
	

App.java

package com.rk.hibernate.n_inheritance3;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;


public class App
{
	private static SessionFactory sf;
	static
	{
		sf = new Configuration()
						.configure()
						.addClass(Animal.class)
						.buildSessionFactory();
	}
	
	@Test
	public void testSave()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
		//貓
		Cat cat = new Cat();
		cat.setName("大花貓");
		cat.setCatchMouse("抓小老鼠");
		
		//猴子
		Monkey monkey = new Monkey();
		monkey.setName("淘氣猴");
		monkey.setEatBanana("吃黃香蕉");
		
		//保存
		session.save(cat);
		session.save(monkey);
		
		session.getTransaction().commit();
		session.close();
	}
	
}

生成的T_Animal_Each表

(14)Hibernate繼承映射

生成的T_Cat_Each表

(14)Hibernate繼承映射

生成的T_Monkey_Each表

(14)Hibernate繼承映射



總結(jié):一個映射文件,存儲所有的子類; 子類父類都對應(yīng)表; 缺點:表結(jié)構(gòu)比較負(fù)責(zé),插入一條子類信息,需要用2條sql: 往父類插入、往子類插入!



2.3、(推薦)每個子類映射一張表, 父類不對應(yīng)表(2張表)


Animal.java

package com.rk.hibernate.n_inheritance4;

public abstract class Animal
{
	private String id;
	private String name;
	public String getId()
	{
		return id;
	}
	public void setId(String id)
	{
		this.id = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	
}

Cat.java

package com.rk.hibernate.n_inheritance4;

public class Cat extends Animal
{
	private String catchMouse;

	public String getCatchMouse()
	{
		return catchMouse;
	}

	public void setCatchMouse(String catchMouse)
	{
		this.catchMouse = catchMouse;
	}

	@Override
	public String toString()
	{
		return "Cat [id=" + getId() + ", name=" + getName() + ", catchMouse=" + catchMouse + "]";
	}
	
}

Monkey.java

package com.rk.hibernate.n_inheritance4;

public class Monkey extends Animal
{
	private String eatBanana;

	public String getEatBanana()
	{
		return eatBanana;
	}

	public void setEatBanana(String eatBanana)
	{
		this.eatBanana = eatBanana;
	}
	
}

Animal.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<!-- 
	繼承映射, 每個類對應(yīng)一張表(父類不對應(yīng)表)
 -->
<hibernate-mapping package="com.rk.hibernate.n_inheritance4" auto-import="true">
	<!-- 
		 abstract="true"  指定實體類對象不對應(yīng)表,即在數(shù)據(jù)庫內(nèi)不生成表
	 -->
	<class name="Animal" table="T_Animal_Final">
		<!-- 如果用union-subclass節(jié)點,主鍵生成策略不能為自增長! -->
		<id name="id" column="id">
			<generator class="uuid"></generator>
		</id>
		<property name="name" column="name"></property>

		<!-- 
			子類:貓  
			union-subclass  
				table 指定為表名, 表的主鍵即為id列
		-->
		<union-subclass name="Cat" table="T_Cat_Final">
			<property name="catchMouse" column="catchMouse"></property>
		</union-subclass>

		<!-- 子類:猴子  -->		
		<union-subclass name="Monkey" table="T_Monkey_Final">
			<property name="eatBanana" column="eatBanana"></property>
		</union-subclass>
	</class>
</hibernate-mapping>	
	

App.java

package com.rk.hibernate.n_inheritance4;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;


public class App
{
	private static SessionFactory sf;
	static
	{
		sf = new Configuration()
						.configure()
						.addClass(Animal.class)
						.buildSessionFactory();
	}
	
	@Test
	public void testSave()
	{
		Session session = sf.openSession();
		session.beginTransaction();
		
		//貓
		Cat cat = new Cat();
		cat.setName("大花貓");
		cat.setCatchMouse("抓小老鼠");
		
		//猴子
		Monkey monkey = new Monkey();
		monkey.setName("淘氣猴");
		monkey.setEatBanana("吃黃香蕉");
		
		//保存
		session.save(cat);
		session.save(monkey);
		
		session.getTransaction().commit();
		session.close();
	}
	
}

生成的T_Animal_Final表,雖然會生成這個表,但是不會存儲數(shù)據(jù)

(14)Hibernate繼承映射

生成的T_Cat_Final表

(14)Hibernate繼承映射

生成的T_Monkey_Final表

(14)Hibernate繼承映射


總結(jié):所有的子類都寫到一個映射文件;父類不對應(yīng)表; 每個子類對應(yīng)一張表。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI