- 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://127.0.0.1/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)
广告