在每个类创建一张表的情况下, 表中不使用Null值的列。 这种方法的缺点是在子类表中创建了重复的列。
在这里,我们需要在父类中使用@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
注释,并在子类中使用@AttributeOverrides
注释。@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
指定正在使用每个具体类策略的表。它应该仅在父类中指定。
@AttributeOverrides
定义该类中的父类属性将被覆盖。 在表结构中,父类表列将被添加到子类表中。
我们来了解映射的层次结构。
在每个具体类一张表的情况下,数据库中将有三个表,每个表表示一个特定的类。
每个表的格结构如下:Employee
类的表结构 -
CREATE TABLE `emp122` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Regular_Employee
类的表结构 -
CREATE TABLE `regemp122` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, `salary` float DEFAULT NULL, `bonus` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Contract_Employee
类的表结构 -
CREATE TABLE `contemp122` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, `pay_per_hour` float DEFAULT NULL, `contract_duration` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
每个具体类的表示例
在这个例子中,我们创建了三个类,并在employee.hbm.xml
文件中提供了这些类的映射。创建一个项目:inheritance2annotation
, 完整的项目结构如下 -
1)创建持久类
您需要创建表示继承的持久化类。 让我们为上面的层次结构创建三个类:
文件:Employee.java
package com.yiibai;
import javax.persistence.*; import javax.persistence.*; @Entity @Table(name = "employee102") @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public class Employee { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id") private int id; @Column(name = "name") 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; } // setters and getters }
文件:Regular_Employee.java
package com.yiibai;
/** * * @author by maxsu * @copyright http://www.yiibai.com * @link download at: http://www.yiibai.com/siteinfo/download.html */ import javax.persistence.*; @Entity @Table(name = "regularemployee102") @AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "id")), @AttributeOverride(name = "name", column = @Column(name = "name")) }) public class Regular_Employee extends Employee { @Column(name = "salary") private float salary; @Column(name = "bonus") private int bonus; public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } public int getBonus() { return bonus; } public void setBonus(int bonus) { this.bonus = bonus; } // setters and getters }
文件:Contract_Employee.java
package com.yiibai;
/** * * @author by maxsu * @copyright http://www.yiibai.com * @link download at: http://www.yiibai.com/siteinfo/download.html */ import javax.persistence.*; @Entity @Table(name = "contractemployee102") @AttributeOverrides({ @AttributeOverride(name = "id", column = @Column(name = "id")), @AttributeOverride(name = "name", column = @Column(name = "name")) }) public class Contract_Employee extends Employee { @Column(name = "pay_per_hour") private float pay_per_hour; @Column(name = "contract_duration") private String contract_duration; public float getPay_per_hour() { return pay_per_hour; } public void setPay_per_hour(float payPerHour) { pay_per_hour = payPerHour; } public String getContract_duration() { return contract_duration; } public void setContract_duration(String contractDuration) { contract_duration = contractDuration; } }
2)在配置文件中添加hbm文件的映射
打开hibernate.cfg.xml文
件,并添加如下映射资源的项:
<mapping class="com.yiibai.Employee" /> <mapping class="com.yiibai.Contract_Employee" /> <mapping class="com.yiibai.Regular_Employee" />
现在配置文件将如下所示:
文件:hibernate.cfg.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration> <session-factory> <property name="hbm2ddl.auto">update</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="connection.username">root</property> <property name="connection.password">123456</property> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="show_sql">true</property> <mapping class="com.yiibai.Employee" /> <mapping class="com.yiibai.Contract_Employee" /> <mapping class="com.yiibai.Regular_Employee" /> </session-factory> </hibernate-configuration>
hbm2ddl.auto
属性定义是用于在数据库中创建自动表。
4)创建存储持久对象的类
在这个类中,我们只是将Employee
对象存储在数据库表中。
文件:MainTest.java
package com.yiibai;
import org.hibernate.*; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; /** * * @author by maxsu * @copyright http://www.yiibai.com * @link download at: http://www.yiibai.com/siteinfo/download.html */ public class MainTest { public static void main(String[] args) { // 但在5.1.0版本汇总,hibernate则采用如下新方式获取: // 1. 配置类型安全的准服务注册类,这是当前应用的单例对象,不作修改,所以声明为final // 在configure("cfg/hibernate.cfg.xml")方法中,如果不指定资源路径,默认在类路径下寻找名为hibernate.cfg.xml的文件 final StandardServiceRegistry registry = new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml").build(); // 2. 根据服务注册类创建一个元数据资源集,同时构建元数据并生成应用一般唯一的的session工厂 SessionFactory sessionFactory = new MetadataSources(registry) .buildMetadata().buildSessionFactory(); /**** 上面是配置准备,下面开始我们的数据库操作 ******/ Session session = sessionFactory.openSession();// 从会话工厂获取一个session // creating transaction object Transaction t = session.beginTransaction(); Employee e1 = new Employee(); e1.setName("用户名-01"); Regular_Employee e2 = new Regular_Employee(); e2.setName("yiibai su"); e2.setSalary(50002); e2.setBonus(5); Contract_Employee e3 = new Contract_Employee(); e3.setName("Mina su"); e3.setPay_per_hour(1010); e3.setContract_duration("15 hours"); session.persist(e1); session.persist(e2); session.persist(e3); t.commit(); session.close(); System.out.println("success"); } }
执行上面代码运行测试即可,应该会自动创建三张表,并插入数据。