- Hibernate 教程
- Hibernate - 首頁
- ORM - 概述
- Hibernate - 概述
- Hibernate - 架構
- Hibernate - 環境
- Hibernate - 配置
- Hibernate - 會話
- Hibernate - 持久化類
- Hibernate - 對映檔案
- Hibernate - 對映型別
- Hibernate - 示例
- Hibernate - O/R 對映
- Hibernate - 級聯型別
- Hibernate - 註解
- Hibernate - 查詢語言
- Hibernate - Criteria 查詢
- Hibernate - 原生 SQL
- Hibernate - 快取
- Hibernate - 實體生命週期
- Hibernate - 批次處理
- Hibernate - 攔截器
- Hibernate - ID 生成器
- Hibernate - 儲存圖片
- Hibernate - log4j 整合
- Hibernate - Spring 整合
- Hibernate - Struts 2 整合
- Hibernate - Web 應用
- 對映表示例
- Hibernate - 每個層次結構一張表
- Hibernate - 每個具體類一張表
- Hibernate - 每個子類一張表
- Hibernate 有用資源
- Hibernate - 問題與解答
- Hibernate - 快速指南
- Hibernate - 有用資源
- Hibernate - 討論
Hibernate - 每個子類一張表
簡介
在 Hibernate 中,Java 類對映到資料庫表。假設我們有一個類,它有幾個子類,Hibernate 提供了三種方法將這些類對映到表中:
每個層次結構一張表
每個具體類一張表
每個子類一張表
讓我們詳細討論一下“每個子類一張表”策略,並透過一個示例進行說明。
每個子類一張表
假設我們有一個類“Shape”,它有兩個子類,“Circle”和“Rectangle”。在這種策略中,我們為每個類建立一個新表。此外,在子類表中,會新增父類所有欄位。因此,我們不需要連線父類表,因為子類表包含了父類所有的欄位。
層次結構中共有三個類。Shape 是父類,Circle 和 Rectangle 是子類。為了對映這些類,我們將使用 *.hbm.xml 檔案中的 joined-subclass 元素,如下所示:
<class name="com.tutorialspoint.Shape" table="shape">
...
<joined-subclass name="com.tutorialspoint.Circle"
table="circle">
<key column="sid"></key>
<property name="radius"></property>
</joined-subclass>
<joined-subclass name="com.tutorialspoint.Rectangle"
table="rectangle">
<key column="rid"></key>
<property name="length"></property>
<property name="width"></property>
</joined-subclass>
...
建立對映類
讓我們建立需要將資料持久化到資料庫中的 POJO 類。
Shape.java
package com.tutorialspoint;
public class Shape {
public int Id;
public String type;
public double area;
public Shape() {
this.type = "Shape";
}
public double calculateArea() {
this.area= 0;
setArea(area);
return area;
}
public int getId() {
return Id;
}
public void setId(int i) {
this.Id = i;
}
public String getType() {
return this.type;
}
public double getArea() {
return area;
}
public void setArea(double i) {
area = i;
}
}
Circle.java
package com.tutorialspoint;
import java.math.*;
public class Circle extends Shape {
private double radius;
public Circle(double rad ) {
this.radius = rad;
this.type = "Circle";
}
@Override
public double calculateArea() {
area = Math.PI * radius * radius;
return area;
}
public void setArea() {
this.area = calculateArea();
}
public double getArea() {
return area;
}
}
Rectangle.java
package com.tutorialspoint;
public class Rectangle extends Shape {
private double length, width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
this.type = "Rectangle";
}
@Override
public double calculateArea() {
return length * width;
}
public void setArea() {
this.area = calculateArea();
}
public double getArea() {
return area;
}
}
建立資料庫表
讓我們在資料庫中建立表。將會有三個表對應於上述物件,您希望提供持久化。假設上述物件需要儲存到以下 RDBMS 表中:
CREATE TABLE students.shape( id int NOT NULL, type VARCHAR(20), area float ); CREATE TABLE students.circle( sid int NOT NULL, radius float ); CREATE TABLE students.rectangle( rid int NOT NULL, length float, width float );
建立對映配置檔案
現在建立一個對映檔案,該檔案指示 Hibernate 如何將定義的類對映到資料庫表。
shape.hbm.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 5.3//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.tutorialspoint.Shape" table="shape">
<id name="id">
<generator class="increment"></generator>
</id>
<property name="type"></property>
<property name="area"></property>
<joined-subclass name="com.tutorialspoint.Circle"
table="circle">
<key column="sid"></key>
<property name="radius"></property>
</joined-subclass>
<joined-subclass name="com.tutorialspoint.Rectangle"
table="rectangle">
<key column="rid"></key>
<property name="length"></property>
<property name="width"></property>
</joined-subclass>
</class>
</hibernate-mapping>
建立 Hibernate 配置檔案
現在為資料庫和其他詳細資訊建立一個 Hibernate 配置檔案。
hibernate.cfg.xml
<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hbm2ddl.auto">update</property>
<property name = "hibernate.dialect">
org.hibernate.dialect.MySQL8Dialect
</property>
<property name = "hibernate.connection.driver_class">
com.mysql.cj.jdbc.Driver
</property>
<!—'students' is the database name -->
<property name = "hibernate.connection.url">
jdbc:mysql:///students
</property>
<property name = "hibernate.connection.username">
root
</property>
<property name = "hibernate.connection.password">
guest123
</property>
<!-- List of XML mapping files -->
<mapping resource = "shape.hbm.xml"/>
</session-factory>
</hibernate-configuration>
將屬性 hbm2ddlauto 設定為 update 將在程式執行期間建立表(如果尚未建立)。
建立應用程式類
最後,我們將建立我們的應用程式類,其中包含 main() 方法以執行應用程式。我們將使用此應用程式來測試“每個具體類一張表”對映。
TestTablePerSubclass.java
package com.tutorialspoint;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class TestTablePerSubclass{ {
public static void main(String[] args) {
// create a hibernate configuration
StandardServiceRegistry ssr=new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
Metadata meta=new MetadataSources(ssr).getMetadataBuilder().build();
// get the sessionfactory and open the session
SessionFactory factory=meta.getSessionFactoryBuilder().build();
Session session=factory.openSession();
// begin the transaction
Transaction t=session.beginTransaction();
// create Shape instance and set details to persist
Shape s1=new Shape();
s1.setType(s1.getType());
s1.setArea(0);
// create Circle instance and set details to persist
Circle c1=new Circle(2);
c1.setArea();
// create Rectangle instance and set details to persist
Rectangle r1 = new Rectangle(3,4);
r1.setArea();
// persist all instances
session.persist(s1);
session.persist(c1);
session.persist(r1);
// commit the transaction and close the session
t.commit();
session.close();
System.out.println(" Successfully persisted 3 classes. Please check your database for results.");
}
}
編譯和執行
執行 TestTablePerHierarchy 二進位制檔案以執行程式。
輸出
您將獲得以下結果,並且記錄將建立在 Shape 表中。
$java TestTablePerHierarchy Successfully persisted 3 classes. Please check your database for results.
如果您檢查您的表,它們應該包含以下記錄:
mysql> select * from shape; +----+-----------+-------+ | id | type | area | +----+-----------+-------+ | 1 | Shape | 0 | | 2 | Circle | 12.56 | | 3 | Rectangle | 12 | +----+-----------+-------+ 3 rows in set (0.00 sec) mysql> select * from circle; +-----+--------+ | sid | radius | +-----+--------+ | 2 | 2 | +-----+--------+ 1 row in set (0.00 sec) mysql> select * from rectangle; +-----+--------+--------+ | rid | length | height | +-----+--------+--------+ | 3 | 3 | 4 | +-----+--------+--------+ 1 row in set (0.00 sec)
廣告