泛化关系即继承关系。
以Product和BookProduct、ClothProduct为例。
其中BookProduct和ClothProduct继承于Product。、
- Product
@Getter@Setter@ToString
public class Product {
private Long id;
private String name;
}
- BookProduct
@Getter@Sette public class BookProduct extends Product{ private String ISBN; @Override public String toString() { return "BookProduct{" + "name='" + super.getName() + '\''+ "ISBN='" + ISBN + '\'' + '}'; } }
- ClothProduct
@Getter@Setter public class ClothProduct extends Product{ private String size; @Override public String toString() { return "ClothProduct{" + "name='" + super.getName() + '\''+ "size='" + size + '\'' + '}'; } }
1、Single Table
- 基本配置
仅需要在父类和子类上标注@Entity即可。
@Entity@Table(name = "product")
public class Product {
// 其余代码略
}
@Getter@Setter@Entity
public class BookProduct extends Product{
// 其余代码略
}
@Getter@Setter@Entity
public class ClothProduct extends Product{
// 其余代码略
}
- 持久化测试
public class ExtendTest {
@Test
public void testSave(){
/* 对象准备 */
Product p = new Product();
p.setName("p");
BookProduct book = new BookProduct();
book.setName("三体");
book.setISBN("12345678");
ClothProduct cloth = new ClothProduct();
cloth.setSize("T恤");
cloth.setSize("XL");
EntityManager em = JPAUtil.GetInstance().getEM();
em.getTransaction().begin();
/* 持久化操作 */
em.persist(p);
em.persist(book);
em.persist(cloth);
em.getTransaction().commit();
em.close();
}
测试结果(数据库表):
- 多态查询测试
public class ExtendTest {
@Before
public void testSave(){
/* 对象准备 */
Product p = new Product();
p.setName("p");
BookProduct book = new BookProduct();
book.setName("三体");
book.setISBN("12345678");
ClothProduct cloth = new ClothProduct();
cloth.setSize("T恤");
cloth.setSize("XL");
EntityManager em = JPAUtil.GetInstance().getEM();
em.getTransaction().begin();
/* 持久化操作 */
em.persist(p);
em.persist(book);
em.persist(cloth);
em.getTransaction().commit();
em.close();
}
@Test
public void testGet(){
EntityManager em = JPAUtil.GetInstance().getEM();
em.getTransaction().begin();
/* 查询 */
BookProduct p = em.find(BookProduct.class, 2l);
System.out.println(p);
em.getTransaction().commit();
em.close();
}
}
测试结果:
- 自定义鉴别器列
1、若需自定义鉴别器列名、列类型。
可父类上对@DiscriminatorColumn标注进行配置,
该标注的name属性为鉴别器列名,discriminatorType为鉴别器列类型。
@DiscriminatorColumn(name = "type_id", discriminatorType = DiscriminatorType.INTEGER)
public class Product {
// 其余代码略
}
阅读DiscriminatorType源代码,可知存在三种类型:
public enum DiscriminatorType {
STRING,
CHAR,
INTEGER;
// 其余代码略
}
2、若需要自定义鉴别器列中,不同类型对应的值。
可在类上配置@DiscriminatorValue的value属性。
如下为Product类上的配置,其余类未进行鉴别器列的配置。
@DiscriminatorColumn(name = "type_id", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue(value = "0")
public class Product {
// 其余代码略
}
执行持久化测试后,数据库表如下:
2、PER TABLE
1、在父类上配置@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
(父类和子类都需配置@Entity)
2、OID生成策略不可为IDENTITY