Hibernate【映射】續篇

小編:管理員 432閱讀 2022.09.14

組件映射

Java主要的類主要有兩種方式

  • 組合關系,組合關系對應的就是組件映射
  • 繼承關系,繼承關系對應的就是繼承映射

組件映射實際上就是將組合關系的數據映射成一張表,組件類和被包含的組件類映射成一張表

有的時候,兩個類的關系明顯不是繼承關系,但兩個類的親密程度很高,在一個類里邊需要用到另外一個類…那么就在類中定義一個變量來維護另一個類的關系,這種就叫組合關系!

需求:汽車和輪子。汽車需要用到輪子,但是輪子的爸爸不可能是汽車吧?

設計數據庫

這里寫圖片描述

設計實體

Wheel.java

public class Wheel {



private int  count;

private int size;



public int getCount() {

return count;

}



public void setCount(int count) {

this.count = count;

}



public int getSize() {

return size;

}



public void setSize(int size) {

this.size = size;

}

}
復制

Car.java,使用變量維護Wheel

package zhongfucheng.aa;



/**

* Created by ozc on 2017/5/7.

*/

public class Car {



private int id;

private String name;

private Wheel wheel;



public Wheel getWheel() {

return wheel;

}



public void setWheel(Wheel wheel) {

this.wheel = wheel;

}



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;

}

}
復制映射表

使用了一個新標簽,組件映射標簽。

















































復制測試
package zhongfucheng.aa;



import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.classic.Session;



/**

* Created by ozc on 2017/5/6.

*/

public class App5 {

public static void main(String[] args) {





//創建對象

Wheel wheel = new Wheel();

Car car = new Car();



//設置屬性

wheel.setCount(43);

wheel.setSize(22);

car.setName("寶馬");



//維護關系

car.setWheel(wheel);

//獲取加載配置管理類

Configuration configuration = new Configuration();





configuration.configure().addClass(Car.class);



//創建Session工廠對象

SessionFactory factory = configuration.buildSessionFactory();



//得到Session對象

Session session = factory.openSession();



//使用Hibernate操作數據庫,都要開啟事務,得到事務對象

Transaction transaction = session.getTransaction();



//開啟事務

transaction.begin();



session.save(car);



//提交事務

transaction.commit();



//關閉Session

session.close();





}

}
復制

這里寫圖片描述

傳統方式繼承

需求:動物、貓、猴子。貓繼承著動物

傳統方式繼承的特點就是:有多少個子類就寫多少個配置文件.

表結構

我們的表應該是這樣的:id和name從Animal中繼承,catchMouse是子類的具體行為。

這里寫圖片描述

實體

Animal.java

package zhongfucheng.aa;



// 動物類

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繼承著Animail

package zhongfucheng.aa;



public class Cat extends Animal{



// 抓老鼠

private String catchMouse;



public String getCatchMouse() {

return catchMouse;

}



public void setCatchMouse(String catchMouse) {

this.catchMouse = catchMouse;

}

}
復制
映射文件

簡單繼承的映射文件很好寫,在屬性上,直接寫父類的屬性就可以了。

但是也有致命的缺點:如果子類有很多,就需要寫很多的配置文件







































復制測試
package zhongfucheng.aa;



import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.classic.Session;



public class App5 {

public static void main(String[] args) {





//創建對象

Cat cat = new Cat();



//設置屬性



cat.setName("大花貓");

cat.setCatchMouse("捉大老鼠");



//獲取加載配置管理類

Configuration configuration = new Configuration();





configuration.configure().addClass(Cat.class);



//創建Session工廠對象

SessionFactory factory = configuration.buildSessionFactory();



//得到Session對象

Session session = factory.openSession();



//使用Hibernate操作數據庫,都要開啟事務,得到事務對象

Transaction transaction = session.getTransaction();



//開啟事務

transaction.begin();



session.save(cat);

//如果取數據時候Animal父類接收的話,需要給出Anmail的全名





//提交事務

transaction.commit();



//關閉Session

session.close();





}

}
復制

這里寫圖片描述


把所有子類映射成一張表

前面我們采用的是:每個子類都需要寫成一個配置文件,映射成一張表

如果子類的結構很簡單,只比父類多幾個屬性。就像上面的例子…我們可以將所有的子類都映射成一張表中

但是呢,這樣是不符合數據庫設計規范的…..因為表中的數據可能是貓,可能是猴子…這明顯是不合適的…

由于表中可能存在貓,存在猴子,為了區分是什么類型的。我們需要使用鑒別器

我們了解一下…

數據表

這里寫圖片描述

實體

實體和上面雷同,只多了一個猴子的實體表

Monkey.java

public class Monkey extends Animal {

// 吃香蕉

private String eatBanana;



public String getEatBanana() {

return eatBanana;

}



public void setEatBanana(String eatBanana) {

this.eatBanana = eatBanana;

}

}
復制映射文件

使用了subClass這個節點和鑒別器





































     







復制測試

加載的是Animal父類的映射文件。保存的是cat和monkey。

package zhongfucheng.aa;



import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.classic.Session;



public class App5 {

public static void main(String[] args) {





//創建對象

Cat cat = new Cat();

Monkey monkey = new Monkey();



//設置屬性

cat.setName("大花貓");

cat.setCatchMouse("小老鼠");

monkey.setEatBanana("吃香蕉");

monkey.setName("大猴子");



//獲取加載配置管理類

Configuration configuration = new Configuration();



//加載Animal的映射文件!

configuration.configure().addClass(Animal.class);



//創建Session工廠對象

SessionFactory factory = configuration.buildSessionFactory();



//得到Session對象

Session session = factory.openSession();



//使用Hibernate操作數據庫,都要開啟事務,得到事務對象

Transaction transaction = session.getTransaction();



//開啟事務

transaction.begin();



session.save(cat);

session.save(monkey);



//提交事務

transaction.commit();



//關閉Session

session.close();





}

}
復制

這里寫圖片描述


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

父類和子類都各對應一張表。那么就有三張表了

這種結構看起來是完全面向對象,但是表之間的結構會很復雜,插入一條子類的信息,需要兩條SQL

數據表設計

這里寫圖片描述

映射文件

使用到了這個節點































































復制測試
package zhongfucheng.aa;



import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.classic.Session;



public class App5 {

public static void main(String[] args) {





//創建對象

Cat cat = new Cat();

Monkey monkey = new Monkey();



//設置屬性

cat.setName("大花貓");

cat.setCatchMouse("小老鼠");

monkey.setEatBanana("吃香蕉");

monkey.setName("大猴子");



//獲取加載配置管理類

Configuration configuration = new Configuration();



//加載類對應的映射文件!

configuration.configure().addClass(Animal.class);



//創建Session工廠對象

SessionFactory factory = configuration.buildSessionFactory();



//得到Session對象

Session session = factory.openSession();



//使用Hibernate操作數據庫,都要開啟事務,得到事務對象

Transaction transaction = session.getTransaction();



//開啟事務

transaction.begin();



session.save(cat);

session.save(monkey);



//提交事務

transaction.commit();



//關閉Session

session.close();





}

}
復制

每保存一個子類對象需要兩條SQL語句!

這里寫圖片描述


(推薦)每個子類映射一張表, 父類不對應表(2張表)
  • 使用過了一張表保存所有子類的數據,這不符合數據庫設計規范
  • 每個子類、父類都擁有一張表..表結構太過于繁瑣..添加信息時,過多的SQL

我們即將使用的是:每個子類映射成一張表,父類不對應表…這和我們傳統方式繼承是一樣的。只不過在hbm.xml文件中使用了這個節點,由于有了這個節點,我們就不需要每個子類都寫一個配置文件了。

數據庫表設計

這里寫圖片描述

映射文件
  • 想要父類不映射成數據庫表,只要在class中配置為abstract即可
  • 使用了union-subclass節點,主鍵就不能采用自動增長策略了。我們改成UUID即可。當然啦,對應的實體id類型要改成String






























































復制測試
package zhongfucheng.aa;



import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.classic.Session;



public class App5 {

public static void main(String[] args) {





//創建對象

Cat cat = new Cat();

Monkey monkey = new Monkey();



//設置屬性

cat.setName("大花貓");

cat.setCatchMouse("小老鼠");

monkey.setEatBanana("吃香蕉");

monkey.setName("大猴子");



//獲取加載配置管理類

Configuration configuration = new Configuration();



//加載類對應的映射文件!

configuration.configure().addClass(Animal.class);



//創建Session工廠對象

SessionFactory factory = configuration.buildSessionFactory();



//得到Session對象

Session session = factory.openSession();



//使用Hibernate操作數據庫,都要開啟事務,得到事務對象

Transaction transaction = session.getTransaction();



//開啟事務

transaction.begin();



session.save(cat);

session.save(monkey);



//提交事務

transaction.commit();



//關閉Session

session.close();





}

}
復制

這里寫圖片描述

組件映射和繼承映射總結

由于我們的傳統繼承映射每個子類都對應一個配置文件,這樣十分麻煩。因此.hbm.xml就給出了幾個節點供我們使用,分別有以下的情況:

  • 子類父類共有一張表subclass
  • 不符合數據庫設計規范
  • 需要使用鑒別器
  • 子類、父類都有自己的表joined-subclass,那么就是三張表
  • 表的結構太過繁瑣
  • 插入數據時要生成SQL至少就要兩條
  • 子類擁有自己的表、父類不對應表【推薦】union-subclass
  • 父類不對應表要使用abstract來修飾
  • 主鍵的id不能使用自增長策略,修改成UUID就好了。對應的JavaBean的id設置成String就好

關聯標簽:
亚洲国产欧美图片,亚洲aⅴ在线av,日韩亚洲综合图片视频,日本av精品在线中文