✍️
이런 걸
배워요!
JPA의 기본기를 탄탄하게 다질 수 있습니다.
JPA의 내부 동작 방식을 이해할 수 있습니다.
객체와 DB 테이블을 올바르게 설계하고 매핑할 수 있습니다.
실무에서 자신있게 JPA를 사용할 수 있습니다.
인프런 강의 : https://www.inflearn.com/course/ORM-JPA-Basic
강의 자료 :
https://github.com/braverokmc79/jpa-basic-lecture-file
소스 :
https://github.com/braverokmc79/ex-jpa-13-1
https://github.com/braverokmc79/jpa-shop
[6] 고급 매핑
22. 상속관계 매핑
강의:
https://www.inflearn.com/course/lecture?courseSlug=ORM-JPA-Basic&unitId=21705&tab=curriculum
목차
• 상속관계 매핑
• @MappedSuperclass
• 실전 예제 - 4. 상속관계 매핑
상속관계 매핑
• 슈퍼타입 서브타입 논리 모델을 실제 물리 모델로 구현하는 방법
• 각각 테이블로 변환 -> 조인 전략
• 통합 테이블로 변환 -> 단일 테이블 전략
• 서브타입 테이블로 변환 -> 구현 클래스마다 테이블 전략
주요 어노테이션
• @Inheritance(strategy=InheritanceType.XXX)
• JOINED: 조인 전략
• SINGLE_TABLE: 단일 테이블 전략
• TABLE_PER_CLASS: 구현 클래스마다 테이블 전략
• @DiscriminatorColumn(name=“DTYPE”)
• @DiscriminatorValue(“XXX”)
1) @Inheritance(strategy = InheritanceType.JOINED) 추가시
Item
@Entity @Inheritance(strategy = InheritanceType.JOINED) public abstract class Item { @Id @GeneratedValue private Long id; private String name; private int price; }
Album
@Entity @Setter @Getter public class Album extends Item{ private String artist; }
Book
@Entity @Setter @Getter public class Book extends Item{ private String author; private String isbn; }
Movie
@Entity @Setter @Getter public class Movie extends Item{ private String director; private String actor; }
Hibernate: create table Album ( artist varchar(255), id bigint not null, primary key (id) ) Hibernate: create table Book ( author varchar(255), isbn varchar(255), id bigint not null, primary key (id) ) Hibernate: create table Item ( id bigint not null, name varchar(255), price integer not null, primary key (id) ) Hibernate: create table Movie ( actor varchar(255), director varchar(255), id bigint not null, primary key (id) )
다음은 개인 적으로 가장 좋은 방식
2) @Inheritance(strategy = InheritanceType.JOINED) 추가후
@DiscriminatorColumn 어노테이션 설정
=> @DiscriminatorColumn 어노테이션 설정하면 DTYPE 추가 된다.
@Entity @Inheritance(strategy = InheritanceType.JOINED) @Setter @Getter @DiscriminatorColumn public class Item { @Id @GeneratedValue private Long id; private String name; private int price; }
package jpashop.home; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; import jpashop.home.domain.Movie; public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf=Persistence.createEntityManagerFactory("hello"); EntityManager em=emf.createEntityManager(); //JPA 의 모든 데이터 변경은 트랜잭션 안에서 실행 되어야 한다. EntityTransaction tx=em.getTransaction(); tx.begin(); try { Movie movie =new Movie(); movie.setDirector("aaa"); movie.setActor("bbb"); movie.setName("바람과함께 사라지다"); movie.setPrice(10000); em.persist(movie); tx.commit(); }catch(Exception e) { tx.rollback(); }finally { em.close(); } emf.close(); } }
=>실행시 결과
만약에 Movie 클래스에 @DiscriminatorValue("M") 어노테이션 // 추가시 타입명 축약 됨
조인 전략
• 장점
• 테이블 정규화
• 외래 키 참조 무결성 제약조건 활용가능
• 저장공간 효율화
• 단점
• 조회시 조인을 많이 사용, 성능 저하
• 조회 쿼리가 복잡함
• 데이터 저장시 INSERT SQL 2번 호출
다음과 같이 SINGLE_TABLE 으로 변경만 하면 단일 테이블 전략 처리 되며 DTYPE 은 반드시 추가 된다.
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
create table Item ( DTYPE varchar(31) not null, id bigint not null, name varchar(255), price integer not null, artist varchar(255), author varchar(255), isbn varchar(255), actor varchar(255), director varchar(255), primary key (id) )
단일 테이블 전략 (InheritanceType.TABLE_PER_CLAS ) (사용하지 말것 )
• 장점
• 조인이 필요 없으므로 일반적으로 조회 성능이 빠름
• 조회 쿼리가 단순함
• 단점
• 자식 엔티티가 매핑한 컬럼은 모두 null 허용
• 단일 테이블에 모든 것을 저장하므로 테이블이 커질 수 있다. 상
황에 따라서 조회 성능이 오히려 느려질 수 있다.
구현 클래스마다 테이블 전략
• 이 전략은 데이터베이스 설계자와 ORM 전문가 둘 다 추천X
• 장점
• 서브 타입을 명확하게 구분해서 처리할 때 효과적
• not null 제약조건 사용 가능
• 단점
• 여러 자식 테이블을 함께 조회할 때 성능이 느림(UNION SQL 필요)
• 자식 테이블을 통합해서 쿼리하기 어려움
23. Mapped Superclass - 매핑 정보 상속
강의 :
https://www.inflearn.com/course/lecture?courseSlug=ORM-JPA-Basic&unitId=21706&tab=curriculum
@MappedSuperclass
• 상속관계 매핑X
• 엔티티X, 테이블과 매핑X
• 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공
• 조회, 검색 불가(em.find(BaseEntity) 불가)
• 직접 생성해서 사용할 일이 없으므로 추상 클래스 권장
@MappedSuperclass
• 테이블과 관계 없고, 단순히 엔티티가 공통으로 사용하는 매핑
정보를 모으는 역할
• 주로 등록일, 수정일, 등록자, 수정자 같은 전체 엔티티에서 공통
으로 적용하는 정보를 모을 때 사용
• 참고: @Entity 클래스는 엔티티나 @MappedSuperclass로 지
정한 클래스만 상속 가능
import java.time.LocalDateTime; import javax.persistence.MappedSuperclass; import lombok.Getter; import lombok.Setter; @MappedSuperclass @Getter @Setter public abstract class BaseEntity { private String createdBy; private LocalDateTime createdDate; private String lastModifiedBy; private LocalDateTime lastModifiedDate; }
@Entity public class Member extends BaseEntity{ @Id @GeneratedValue private Long id; @Column(name="USERNAME") private String username; }
24. 실전 예제 4 - 상속관계 매핑
강의 :
https://www.inflearn.com/course/lecture?courseSlug=ORM-JPA-Basic&unitId=21707&tab=curriculum
요구사항 추가
• 상품의 종류는 음반, 도서, 영화가 있고 이후 더 확장될 수 있다.
• 모든 데이터는 등록일과 수정일이 필수다.
BaseEntity
import java.time.LocalDateTime; import javax.persistence.MappedSuperclass; import lombok.Getter; import lombok.Setter; @MappedSuperclass @Getter @Setter public abstract class BaseEntity { private String createdBy; private LocalDateTime createdDate; private String lastModifiedBy; private LocalDateTime lastModifiedDate; }
Item
import java.util.ArrayList; import java.util.List; import javax.persistence.Column; import javax.persistence.DiscriminatorColumn; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.ManyToMany; import lombok.Getter; import lombok.Setter; @Entity @Getter @Setter @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn public abstract class Item extends BaseEntity{ @Id @GeneratedValue @Column(name="ITEM_ID") private Long id; private String name; private String price; private int stockQuantity; @ManyToMany(mappedBy = "items") private List<Cartegory> cartegories=new ArrayList<>(); }
Album
@Entity @Getter @Setter public class Album extends Item{ private String artist; private String etc; }
Book
@Entity @Getter @Setter public class Book extends Item{ private String author; private String isbn; }
Movie
@Entity @Getter @Setter public class Movie extends Item{ private String director; private String actor; }
이미지 주소
create table Album ( artist varchar(255), etc varchar(255), ITEM_ID bigint not null, primary key (ITEM_ID) ) Hibernate: create table Book ( author varchar(255), isbn varchar(255), ITEM_ID bigint not null, primary key (ITEM_ID) ) Hibernate: create table Cartegory ( CARTEGORY_ID bigint not null, createdBy varchar(255), createdDate timestamp, lastModifiedBy varchar(255), lastModifiedDate timestamp, name varchar(255), PARENT_ID bigint, primary key (CARTEGORY_ID) ) Hibernate: create table CATEGORY_ITEM ( CATEGOYR_ID bigint not null, ITEM_ID bigint not null ) Hibernate: create table Delivery ( DELIVERY_ID bigint not null, createdBy varchar(255), createdDate timestamp, lastModifiedBy varchar(255), lastModifiedDate timestamp, city varchar(255), status integer, street varchar(255), zipcode varchar(255), primary key (DELIVERY_ID) ) Hibernate: create table Item ( DTYPE varchar(31) not null, ITEM_ID bigint not null, createdBy varchar(255), createdDate timestamp, lastModifiedBy varchar(255), lastModifiedDate timestamp, name varchar(255), price varchar(255), stockQuantity integer not null, primary key (ITEM_ID) ) Hibernate: create table Member ( MEMBER_ID bigint not null, createdBy varchar(255), createdDate timestamp, lastModifiedBy varchar(255), lastModifiedDate timestamp, city varchar(255), name varchar(255), street varchar(255), zipcode varchar(255), primary key (MEMBER_ID) ) Hibernate: create table Movie ( actor varchar(255), director varchar(255), ITEM_ID bigint not null, primary key (ITEM_ID) ) Hibernate: create table OrderItem ( ORDER_ITEM_ID bigint not null, createdBy varchar(255), createdDate timestamp, lastModifiedBy varchar(255), lastModifiedDate timestamp, count integer not null, oderPrice integer not null, ITEM_ID bigint, ORDER_ID bigint, primary key (ORDER_ITEM_ID) ) Hibernate: create table ORDERS ( ORDER_ID bigint not null, createdBy varchar(255), createdDate timestamp, lastModifiedBy varchar(255), lastModifiedDate timestamp, orderDate timestamp, status varchar(255), DELIVERY_ID bigint, MEMBER_ID bigint, primary key (ORDER_ID) )
댓글 ( 4)
댓글 남기기