백엔드 개발자
JPA 기본 정리 #2 본문
객체와 테이블 매핑
- @Entity 엔티티 선언
- @Id : primary key 매핑, @GeneratedValue : 키 생성방법 지정, strategy 설정해줄 수 있다.
- 기본적으로 GenerationType.Auto 가 디폴트 값이다.
- GenerationType 의 종류
- IDENTITY - auto increment 방식 (이 경우 jpa 영속성 컨텍스트에 들어갈 때 id 값이 있는 상태여야 하므로 커밋시점이 아닌 저장메서드를 호출할 때 바로 db로 저장이 된다.
- SEQUENCE - DB에 저장되어있는 마지막 키값을 불러와 그 다음 값으로 id 설정. (allocationSize를 설정하여 미리 사용할 키값들을 정해놓은 후 사용가능. 매번 db를 조회하지 않아도 됨)
- TABLE
- AUTO
- AUTO는 데이터베이스에 맞춰 위 세개 중 자동으로 선택해준다.
- @Column : 컬럼 매핑
- 테이블 컬럼과 객체 필드의 이름이 다를 경우 name 설정.
- nullable, updatable, size 등 지정 가능.
- 다양한 연관관계에 따라 @ManyToOne, @OneToOne, @OneToMany등을 설정할 수 있다.
- 기본 테이블에 맞춘 설계가 아닌 객체다운 설계를 하면 연관관계 매핑을 설정해 줌으로써 매핑이 가능하게 해준다.
- ManyToOne, OneToOne에서는 @JoinColumn 으로 매핑할 테이블의 키를 지정해준다.
- OneToMany 에서는 mappedBy 로 연관관계 주인을 지정해준다.
- 기본 테이블에 맞춘 설계가 아닌 객체다운 설계를 하면 연관관계 매핑을 설정해 줌으로써 매핑이 가능하게 해준다.
연관관계 매핑 주의점
- 양방향 매핑을 할 경우 ToString, Lombok , JSON 생성 라이브러리를 사용할 때 무한참조(루프)가 일어날 수 있다.
- 값의 변경이 일어날 경우 양방향 모두 수정해 주어야 한다.
- 연관관계 설정에서 @OneToMany 에 mappedBy 를 설정함으로써 연관관계의 값이 일치하도록 설정해주지만 순수 자바상태에서의 값이 일치하지 않으면 영속성 컨텍스트를 참조할 경우나 테스트 코드를 작성할 때 불일치가 있을 수 있다.
⇒ 웬만하면 단반향 참조를 하는 것이 좋다.
필요한 경우 양방향 참조를 하며 연관관계 편의 메소드를 생성하여 잘 관리하자. 무한 루프 조심
연관관계
- 다대일 [N:1]
- 일대다 [1:N]
- 일대일 [1:1]
- 다대다 [N:M]
- 다대다 관계는 실무에서 쓰기 어렵기 때문에 일대다 & 다대일로 풀어줘야한다.
- @ManyToMany로 JoinTable을 설정하여 양쪽의 테이블의 키를 이용한 중간테이블을 만들 수 있는데
- 테이블 필드가 더 필요한 경우가 많고 두 개의 primarykey를 합쳐서 중간테이블의 primarykey로 이용하기 때문에 종속적이게 된다. 새로운 테이블(엔티티)를 생성하는 것이 유지보수에도 더 편리하다
상속 전략
- JAVA 에서는 상속이 가능한데 이것을 3가지 전략으로 지원해준다.
- 조인 전략
- 자식 테이블들은 각 부모의 pk를 fk로 갖고 자식의 추가 컬럼들을 갖는다.
- 단일 테이블 전략
- 한 테이블안에 부모와 자식들의 모든 컬럼을 갖는다.
- 구현 클래스마다 테이블 전략
- 각각 자식테이블에서 부모의 컬럼 + 자식 컬럼들을 갖는다.
- 조인 전략
이러한 전략들은 상속을 구현한 코드에서 부모 클래스에 어노테이션을 지정해주는 것만으로
코드 변경없이 쉽게 변경할 수 있다.
상속 전략 지정
@Inheritance(strategy = InheritanceType.xxx)
- 지정한 전략을 사용해서 테이블을 생성해준다.
- JOINED , SINGLE_TABLE, TABLE_PER_CLASS 가 있다.
@DiscriminatorColumn
- 부모클래스에 구분에 필요한 DTYPE을 생성해준다.
- 단일테이블 전략에서는 DTYPE 구분이 필수적이기 때문에 지정을 안해도 자동으로 생성된다.
상속 전략들의 장단점
- 조인 전략
- 장점
- 테이블 정규화로 객체지향적인 설계라 할 수 있다.
- 저장공간의 효율화
- 단점
- 조회시 조인을 많이 사용하여 성능이 저하될 수 있다.
- 조회 쿼리가 복잡해진다.
- 장점
- 단일 테이블 전략
- 장점
- 테이블이 단순해지고 조회 쿼리도 단순해진다.
- 조인이 필요 없으므로 조회 속도가 빨라진다. (성능 업)
- 단점
- 필요없는 컬럼들도 모두 생성하여야 한다. ( null 허용)
- 테이블이 커져서 조회 성능이 오히려 느려질 수 있다.
- 공간 낭비
- 장점
- 구현 클래스마다 테이블 전략
- 장점
- 각 테이블 마다 맞춤이므로 명확하게 구분하여 처리 할 수 있다.
- not null 제약조건을 사용할 수 있다.
- 단점
- 여러 자식 테이블을 함께 조회하면 성능이 안 좋아져 느려진다.
- 자식 테이블 통합하여 쿼리문 작성이 어려워진다.
- 각 구현 클래스마다 중복 컬럼들이 많아지므로 부모 클래스의 필드가 변경이 되면 자식
- 테이블의 모든 값들을 변경해 주어야 한다.
- 장점
⇒ 이 전략은 객체지향관점에서나 데이터베이스 설계 관점에서 봐도 모두 사용하지 않는 것이 좋다.
MappedSuperclass
보통 공통으로 상속받을 클래스를 지정할 때 사용한다.
@Entity와 다른 점은 이 클래스를 따로 테이블로 만드는 것이 아닌 정말 그냥 상속 용도로만 쓰인다는 것이다.
Entity에서 상속을 하려면 Entity 나 MappedSuperclass 만 가능하기 때문에 테이블로 관리하지 않을 건데 공통으로 필요한 속성들이 있다면 이것을 활용할 수 있다.
- 인프런 김영한님의 JPA 기본편을 듣고 정리한 내용입니다 -
'스프링 > JPA' 카테고리의 다른 글
JPA 기본 정리 #4 (0) | 2023.09.03 |
---|---|
JPA 기본 정리 #3 (0) | 2023.09.03 |
JPA 기본 정리 #1 (0) | 2023.08.31 |
Comments