인프런 강의 - 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편(링크) 참고
@Entity
public abstract class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int age;
private String address;
private String phone;
//getter, setter, ...
}
@Entity
public class Student extends Member {
private int grade;
private int clazz;
//getter, setter, 생성자, 생성 메소드, ...
}
@Entity
public class Teacher extends Member{
private String subject;
private String ect;
//getter, setter, 생성자, 생성 메소드, ...
}
@Entity
public class Staff extends Member {
private int salary;
private LocalDate hiredDate;
//getter, setter, 생성자, 생성 메소드, ...
}
@Inheritance
어노테이션을 사용하여 상속 전략을 지정@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "D_TYPE")
public abstract class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//...
}
MEMBER
엔티티만 조회한다고 했을때, 조금 더 독립적으로 쓸 수 있다.create table Member (
D_TYPE varchar(31) not null,
id bigint generated by default as identity,
address varchar(255),
age integer not null,
phone varchar(255),
primary key (id)
)
create table Student (
clazz integer not null,
grade integer not null,
id bigint not null,
primary key (id)
)
create table Teacher (
ect varchar(255),
subject varchar(255),
id bigint not null,
primary key (id)
)
create table Staff (
hiredDate date,
salary integer not null,
id bigint not null,
primary key (id)
)
Student student = new Student(18, "서울", "010-1234-1234", 2, 10);
em.persist(student);
Teacher teacher = new Teacher(30, "경기도", "010-2345-2345", "수학", "");
em.persist(teacher);
Staff staff = new Staff(30, "서울", "010-3456-3456", 350, LocalDate.of(2010, 10, 31));
em.persist(staff);
em.find(Student.class, 1L);
select
student0_.id as id2_6_0_,
student0_1_.address as address3_6_0_,
student0_1_.age as age4_6_0_,
student0_1_.phone as phone5_6_0_,
student0_.clazz as clazz1_12_0_,
student0_.grade as grade2_12_0_
from
Student student0_
inner join
Member student0_1_
on student0_.id=student0_1_.id
where
student0_.id=1
학생
엔티티만 저장해도 멤버
까지 INSERT문이 날라감멤버
테이블을 1개
만들고 그 테이블에 모든 정보를 담고 있다.@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "D_TYPE")
public abstract class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//...
}
create table Member (
DTYPE varchar(31) not null,
id bigint generated by default as identity,
address varchar(255),
age integer not null,
phone varchar(255),
hiredDate date,
salary integer,
clazz integer,
grade integer,
ect varchar(255),
subject varchar(255),
primary key (id)
)
Student student = new Student(18, "서울", "010-1234-1234", 2, 10);
em.persist(student);
Teacher teacher = new Teacher(30, "경기도", "010-2345-2345", "수학", "");
em.persist(teacher);
Staff staff = new Staff(30, "서울", "010-3456-3456", 350, LocalDate.of(2010, 10, 31));
em.persist(staff);
em.find(Student.class, 1L);
select
student0_.id as id2_6_0_,
student0_.address as address3_6_0_,
student0_.age as age4_6_0_,
student0_.phone as phone5_6_0_,
student0_.clazz as clazz8_6_0_,
student0_.grade as grade9_6_0_
from
Member student0_
where
student0_.id=?
and student0_.DTYPE='Student'
학생
을 저장했는데, 멤버
의 INSERT문이 날라간다. 이는 혼란을 줄 수 있는 부분@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//...
}
create table Staff (
id bigint not null,
address varchar(255),
age integer not null,
phone varchar(255),
hiredDate date,
salary integer not null,
primary key (id)
)
create table Student (
id bigint not null,
address varchar(255),
age integer not null,
phone varchar(255),
clazz integer not null,
grade integer not null,
primary key (id)
)
create table Teacher (
id bigint not null,
address varchar(255),
age integer not null,
phone varchar(255),
ect varchar(255),
subject varchar(255),
primary key (id)
)
Student student = new Student(18, "서울", "010-1234-1234", 2, 10);
em.persist(student);
Teacher teacher = new Teacher(30, "경기도", "010-2345-2345", "수학", "");
em.persist(teacher);
Staff staff = new Staff(30, "서울", "010-3456-3456", 350, LocalDate.of(2010, 10, 31));
em.persist(staff);
em.find(Student.class, 1L);
select
student0_.id as id1_6_0_,
student0_.address as address2_6_0_,
student0_.age as age3_6_0_,
student0_.phone as phone4_6_0_,
student0_.clazz as clazz1_12_0_,
student0_.grade as grade2_12_0_
from
Student student0_
where
student0_.id=1
em.createQuery("select m from Member m", Member.class).getResultList();
select
member0_.id as id1_6_,
member0_.address as address2_6_,
member0_.age as age3_6_,
member0_.phone as phone4_6_,
member0_.hiredDate as hireddat1_11_,
member0_.salary as salary2_11_,
member0_.clazz as clazz1_12_,
member0_.grade as grade2_12_,
member0_.ect as ect1_13_,
member0_.subject as subject2_13_,
member0_.clazz_ as clazz_
from (
select
id,
address,
age,
phone,
hiredDate,
salary,
null as clazz,
null as grade,
null as ect,
null as subject,
1 as clazz_
from Staff
union all
select
id,
address,
age,
phone,
null as hiredDate,
null as salary,
clazz,
grade,
null as ect,
null as subject,
2 as clazz_
from Student
union all
select
id,
address,
age,
phone,
null as hiredDate,
null as salary,
null as clazz,
null as grade,
ect,
subject,
3 as clazz_
from Teacher) member0_
JOINED
를 사용하는 것이 좋아 보임SINGLE_TABLE
고려