Hibernate 继承映射笔记 博客分类: Hibernate HibernateOO
程序员文章站
2024-02-04 22:30:04
...
Hibernate 的继承映射体系提供了一个OO方式的建模方法,有时为了解决复杂的对象关系,用继承映射可以以OO的方式优雅的设计表,操作POJO,为了不混乱,在使用时清晰的选择表关联方式,特做笔记。
方式1: 对一个继承体系,只用一个表保存数据
说明 : 这种方式下,POJO仍然用继承的方式表述,但数据库里只用一个表来保存所有继承体系中的表数据
hibernate 用一个鉴别器字段来区分数据属于那个POJO,每个POJO的鉴别器值在该体系中应该是唯一的,你在每个子类中生命子类的属性,在父类中声明的公用字段,而所有子类中的持久化属性都将作为这个表的一个列.
父类:Panel
package org.jackysoft.entity; import java.io.Serializable; import javax.persistence.*; import org.hibernate.annotations.GenericGenerator; @Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @DiscriminatorColumn( name="planetype", discriminatorType=DiscriminatorType.STRING ) @DiscriminatorValue("Plane") public class Plane implements Serializable { /** * */ private static final long serialVersionUID = 4901135581088517395L; @Id @GeneratedValue(generator="system-hilo") @GenericGenerator(name="system-hilo", strategy = "hilo") private int id; public void setId(int id) { this.id = id; } public int getId() { return id; } }
两个子类:
package org.jackysoft.entity; import javax.persistence.*; @Entity @DiscriminatorValue("A320") public class A320 extends Plane { /** * */ private static final long serialVersionUID = 443224501993619616L; private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } }
package org.jackysoft.entity; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @Entity @DiscriminatorValue("B320") public class B320 extends Plane { /** * */ private static final long serialVersionUID = -1769971860887308527L; private String bName; public void setbName(String bName) { this.bName = bName; } public String getbName() { return bName; } }
生成的数据库表DDL
CREATE TABLE `plane` ( `planetype` varchar(31) NOT NULL, `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, `bName` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) )
数据库表内容
方式2: 连接子类策略
说明:父子类之间不需要鉴别器类识别,父类申明的属性放在父类表中,子类的属性放在子类表中,当查询子类时用内连接的方法取出父类和子类属性,生成子类的POJO
这种情况下,各自保存各自的属性.父子类之间关联通过外键关系类维持
父类:
package org.jackysoft.entity; import java.io.Serializable; import java.util.Calendar; import javax.persistence.*; import org.hibernate.annotations.GenericGenerator; @Entity @Inheritance(strategy = InheritanceType.JOINED) public class Cat implements Serializable { /** * */ private static final long serialVersionUID = 8293438353402096985L; private String id; private Calendar birthday; @Id @GeneratedValue(generator = "cat-uuid") @GenericGenerator(name = "cat-uuid", strategy = "uuid") String getId() { return id; } public void setId(String id) { this.id = id; } public void setBirthday(Calendar birthday) { this.birthday = birthday; } public Calendar getBirthday() { return birthday; } } package org.jackysoft.entity; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; @Entity @PrimaryKeyJoinColumn(name = "CAT") public class DomesticCat extends Cat { /** * */ private static final long serialVersionUID = 8576737344166525594L; private String name; private int age; public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } }
DDL:
CREATE TABLE `cat` ( `id` varchar(255) NOT NULL, `birthday` datetime DEFAULT NULL, PRIMARY KEY (`id`) )
CREATE TABLE `domesticcat` ( `name` varchar(255) DEFAULT NULL, `CAT` varchar(255) NOT NULL, `age` int(11) NOT NULL, PRIMARY KEY (`CAT`), KEY `FK24E5F1B81C0CC455` (`CAT`), CONSTRAINT `FK24E5F1B81C0CC455` FOREIGN KEY (`CAT`) REFERENCES `cat` (`id`) )
插入一条数据后
方法3:每个具体类一张表
说明:这种情况下,每个具体类映射一张表,而每个表保存这个类的所有持久化属性,当然这时也包括从父类继承过来的属 性,其实诚如官方所言,和单独映射每个类都一样,可是如果你为了使用对象见的OO多态属性可以这么映射
@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public class Flight implements Serializable { ... }