스프링

 

✍️
이런 걸
배워요!

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;
}

 

 

이미지 주소

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6E8sqZWUKy5nx-DIbXxhbo-F6DNWaRQE7Cglv5U3GR7-iWZmc_6Z1_tv49Vkud3cXrLKDTAI8ZUEDWA3ygIwuBtwpw3lpiWP7xJTNlL4dXzt5WeeD0ESf5loE93d0XRlEbBJYpLg5hAEv7pAMtqzgZ50b-LykE1GcVj2pVVQy0u-7GtCA8WkMXVdmxg/s2531/2023-02-24%2015%2018%2008.png

 

 

 

 

 

 

 

 

 

 

 

 

    
    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)
    )

 

 

 

 

 

about author

PHRASE

Level 60  라이트

A man is more or less what he looks. (사람은 대체로 외모대로다.)

댓글 ( 4)

댓글 남기기

작성