联合子类策略

这种情况下子类的字段被映射到各自的表中,这些字段包括父类中的字段,并执行一个join操作来实例化子类。

举例

如果实体类Teacher继承实体类Person,实体类Student也继承自实体Person,

会映射成3个表,子表不包含父表的属性,子表只有子类的属性,子表主键外键关联父表的id

这种策略超类会被映射成一个单独的表,每个子类也会映射成一个单独的表。子类对应的表中只包括自身属性对应的字段,默认情况下使用主键作为超类对应的表的外键。

这种策略对于实体间的多态关系提供了很好的支持。但缺点是实例化子类实例时需要一个或多个表的关联操作。在深层次的继承结构中,这会导致性能很低。

配置

注解为:@Inheritance(strategy = InheritanceType.JOINED)

ddl语句

CREATE TABLE `t_person` (
`type` int(11) NOT NULL,
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; CREATE TABLE `t_teacher` (
`address` varchar(255) DEFAULT NULL,
`id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_8ik5mbfy94c9cdklxfo2wqgg9` FOREIGN KEY (`id`) REFERENCES `t_person` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `t_student` (
`school` varchar(255) DEFAULT NULL,
`id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_bdp2c9ntgnbd0ydfj1fwqa7l2` FOREIGN KEY (`id`) REFERENCES `t_person` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Person

package com.jege.jpa.extend;

import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table; /**
* @author JE哥
* @email 1272434821@qq.com
* @description:父类
*/
@Entity
@Table(name = "t_person")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.INTEGER)
public class Person {
@Id
@GeneratedValue
private Long id;
private String name; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

Teacher

package com.jege.jpa.extend;

import javax.persistence.Entity;
import javax.persistence.Table; /**
* @author JE哥
* @email 1272434821@qq.com
* @description:子类
*/
@Entity
@Table(name = "t_teacher")
public class Teacher extends Person {
private String address; public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
} }

Student

package com.jege.jpa.extend;

import javax.persistence.Entity;
import javax.persistence.Table; /**
* @author JE哥
* @email 1272434821@qq.com
* @description:子类
*/
@Entity
@Table(name = "t_student")
public class Student extends Person {
private String school; public String getSchool() {
return school;
} public void setSchool(String school) {
this.school = school;
} }

MainTest

package com.jege.jpa.extend;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence; import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test; /**
* @author JE哥
* @email 1272434821@qq.com
* @description:继承测试
*/
public class MainTest {
private static EntityManagerFactory entityManagerFactory = null;
private EntityManager entityManager = null; @BeforeClass
public static void setUpBeforeClass() throws Exception {
entityManagerFactory = Persistence.createEntityManagerFactory("com.jege.jpa");
} @Before
public void setUp() throws Exception {
entityManager = entityManagerFactory.createEntityManager();
} @Test
public void persist() {
Person person = new Person();
person.setName("jege"); Teacher teacher = new Teacher();
teacher.setName("仓老师");
teacher.setAddress("北京"); Student student = new Student();
student.setName("机械师");
student.setSchool("上海"); entityManager.getTransaction().begin();
entityManager.persist(student);
entityManager.persist(teacher);
entityManager.persist(person);
entityManager.getTransaction().commit();
} @Test
public void find() {
persist(); entityManager.clear();
Student student = entityManager.find(Student.class, 1L);
System.out.println(student.getSchool());
} @After
public void tearDown() throws Exception {
if (entityManager != null && entityManager.isOpen())
entityManager.close();
} @AfterClass
public static void tearDownAfterClass() throws Exception {
if (entityManagerFactory != null && entityManagerFactory.isOpen())
entityManagerFactory.close();
}
}

其他关联项目

源码地址

https://github.com/je-ge/jpa

如果觉得我的文章对您有帮助,请打赏支持。您的支持将鼓励我继续创作!谢谢!



JPA 系列教程16-继承-联合子类-JOINED的更多相关文章

  1. JPA 系列教程17-继承-独立表-TABLE_PER_CLASS

    PerTable策略 每个具体的类一个表的策略 举例 这种映射策略每个类都会映射成一个单独的表,类的所有属性,包括继承的属性都会映射成表的列. 这种映射策略的缺点是:对多态关系的支持有限,当查询涉及到 ...

  2. JPA 系列教程13-复合主键-@EmbeddedId+@Embeddable

    复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id和复合主键-2个@Id+ ...

  3. JPA 系列教程12-复合主键-2个@Id+@IdClass

    复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id一样 Airline p ...

  4. JPA 系列教程21-JPA2.0-@MapKeyColumn

    @MapKeyColumn 用@JoinColumn注解和@MapKeyColumn处理一对多关系 ddl语句 CREATE TABLE `t_employee` ( `id` bigint(20) ...

  5. JPA 系列教程10-双向一对一关联表

    双向一对一关联表的ddl语句 CREATE TABLE `t_person` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255 ...

  6. JPA 系列教程9-双向一对一唯一外键

    双向一对一唯一外键的ddl语句 CREATE TABLE `t_person` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(25 ...

  7. JPA 系列教程7-双向多对多

    双向多对多的ddl语句 同单向多对多表的ddl语句一致 Student package com.jege.jpa.many2many; import java.util.HashSet; import ...

  8. JPA 系列教程5-双向一对多

    双向一对多的ddl语句 同单向多对一,单向一对多表的ddl语句一致 Product package com.jege.jpa.one2many; import javax.persistence.En ...

  9. JPA 系列教程4-单向一对多

    JPA中的@OneToMany @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToMany { Class tar ...

随机推荐

  1. dplyr 数据操作 常用函数(5)

    继续来了解dplyr中的其他有用函数 1.sample() 目的是可以从一个数据框中,随机抽取一些行,然后组成新的数据框. sample_n(tbl, size, replace = FALSE, w ...

  2. stm32

    GPIO NVIC TIME USART ONE WIRE IIC SPI PWM ADC LCD XPT UCOSiii移植 定时器 蓝牙 陀螺仪

  3. 原 iOS深入学习(Block全面分析)http://my.oschina.net/leejan97/blog/268536

    原 iOS深入学习(Block全面分析) 发表于1年前(2014-05-24 16:45)   阅读(26949) | 评论(14) 39人收藏此文章, 我要收藏 赞21 12月12日北京OSC源创会 ...

  4. JS:JSP Servlet

    Servlet 是在服务器上运行的小程序.这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果得到为用户进行 ...

  5. NDEF消息解析实例[转]

      问题:按照NDEF消息格式来解析下列Hex串? D1 02 1F 53 70 91 01 0E 54 02  65 6E 68 65 6C 6C 6F 20 77 6F  72 6C 64 51 ...

  6. Voting

    Voting time limit per test 1 second memory limit per test 256 megabytes input standard input output ...

  7. sf中标准的分页功能介绍

    世上本无事,庸人自扰之.我喜欢一个相对比较安静的环境去学习和工作,希望在一个掉一根针的声音都能够听到的环境中,但是有时候往往相反,一片嘈杂,我改变不了周围的环境,只能改变自己,其实这些都没有什么,也许 ...

  8. 《JavaScript高级程序设计》读书笔记 ---小结

    对象在JavaScript 中被称为引用类型的值,而且有一些内置的引用类型可以用来创建特定的对象,现简要总结如下: 引用类型与传统面向对象程序设计中的类相似,但实现不同: Object 是一个基础 ...

  9. JUit——(三)JUnit核心对象(测试、测试类、Suit和Runner)

    JUnit的核心对象:测试.测试类.测试集(Suite).测试运行器 1. 测试: @Test注释的.公共的.不带有任何参数.并且返回void类型的方法 2. 测试类: 公共的,包含对应类的测试方法的 ...

  10. html5权威指南:表格元素

    第十一章:表格元素                                                                                           ...