일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Intellij
- 어노테이션
- 프로그래머스
- 테스트 코드
- Kafka
- Github Actions
- algorithm
- 아키텍처
- CI/CD
- JPA
- JWT
- trouble shooting
- MSA
- aop
- EC2
- docker
- 객체지향원칙
- Redis
- swagger
- Java
- 멀티 모듈
- querydls
- spring boot
- springboot
- rabbitmq
- Til
- DevOps
- AWS
- testcode
- 유효성 검사
- Today
- Total
개발노트
25.02.12 Spring Boot JPA 에서 엔티티 간의 연관관계 매핑 본문
개요
오랜만에 프로젝트를 설계하면서 ERD를 작성했는데 연관관계에 대해 내 기억이 너무 흐려져 다시 한번 정리하고싶어졌다.
Spring Boot JPA 에서 엔티티 간의 연관관계 매핑
연관관계의 종류
- 1:1 (One-to-One)
- 하나의 엔티티가 다른 엔티티 하나와 연결된 경우
- 1:N (One to Many)
- 하나의 엔티티가 여러 엔티티와 연관된 경우
- N:1 (Many-to-One)
- 여러 엔티티가 하나의 엔티티와 연관된 경우
- N:M (Many-to-Many)
- 여러 엔티티가 여러 엔티티와 연관된 경우. (중간 테이블 필요)
연관 관계 어노테이션 설명 및 설정
@OneToOne (1:1 관계)
1:1 관계를 매핑할 때 사용한다. 하나의 엔티티가 다른 엔티티 하나와 연결된다. 주로 두 테이블의 기본 키 또는 외래 키를 사용해 연결한다.
주요속성
- cascade
- 부모 엔티티의 작업(저장, 삭제 등)이 자식 엔티티에 전파되도록 설정
- 값 : CascdeType.All , PERSIST, MERGE, REMOVE, REFRESH, DETACH
- 예 : cascade = CascadeType.ALL (부모와 자식을 함께 저장/삭제)
- fetch
- 연관된 엔티티를 로드하는 방식 설정
- FetchType.LAZY (지연 로딩) : 연관된 엔티티를 실제 사용시에만 로드
- FetchType.EAGER (즉시 로딩) : 연관된 엔티티를 즉시 로드
- optional
- 관계의 대상이 null이어도 허용 여부를 설정
- 기본값 true (null 허용)
@OneToMany (1:N 관계)
1:N 관계를 매핑할 떄 사용한다. 하나의 엔티티가 여러 엔티티를 참조한다. mappedBy로 주인 명시가 필요하다
주로 양방향 연관 관계에서 사용된다.
주요속성
- mappedBy
- 양방향 관계에서 주인을 결정
- 주인이 아닌 곳은 DB 연관관계 변경 반영 불가
- 값 : 반대쪽 엔티티에서 관계를 설정한 필드명
- cascade
- 부모 엔티티의 작업(저장, 삭제 등)이 자식 엔티티에 전파되도록 설정
- 값 : CascdeType.All , PERSIST, MERGE, REMOVE, REFRESH, DETACH
- 예 : cascade = CascadeType.ALL (부모와 자식을 함께 저장/삭제)
- fetch
- 연관된 엔티티를 로드하는 방식 설정
- FetchType.LAZY (지연 로딩) : 연관된 엔티티를 실제 사용시에만 로드
- FetchType.EAGER (즉시 로딩) : 연관된 엔티티를 즉시 로드
- orphanRemoval
- 부모 엔티티에서 제거된 자식 엔티티를 자동으로 삭제
- 값 : ture 또는 flase (기본값 : false)
@ManyToOne (N:1 관계)
N:1 관계를 매핑할 때 사용한다. 여러 엔티티가 하나의 엔티티를 참조하는 경우 사용된다. 연관관계의 주인으로 설정된다.
주요속성
- cascade
- 부모 엔티티의 작업(저장, 삭제 등)이 자식 엔티티에 전파되도록 설정
- 값 : CascdeType.All , PERSIST, MERGE, REMOVE, REFRESH, DETACH
- 예 : cascade = CascadeType.ALL (부모와 자식을 함께 저장/삭제)
- fetch
- 연관된 엔티티를 로드하는 방식 설정
- FetchType.LAZY (지연 로딩) : 연관된 엔티티를 실제 사용시에만 로드
- FetchType.EAGER (즉시 로딩) : 연관된 엔티티를 즉시 로드
- optional
- 관계의 대상이 null이어도 허용 여부를 설정
- 기본값 true (null 허용)
@ManytoMany (N:M 관계)
N:M 관계를 매핑할 때 사용한다. 두 엔티티가 다대다 관계로 연결된 경우 사용되고 중간 테이블이 필요하며, 이를 설정하기 위해 @JoinTable을 사용한다.
주요속성
- cascade
- 부모 엔티티의 작업(저장, 삭제 등)이 자식 엔티티에 전파되도록 설정
- 값 : CascdeType.All , PERSIST, MERGE, REMOVE, REFRESH, DETACH
- 예 : cascade = CascadeType.ALL (부모와 자식을 함께 저장/삭제)
- fetch
- 연관된 엔티티를 로드하는 방식 설정
- FetchType.LAZY (지연 로딩) : 연관된 엔티티를 실제 사용시에만 로드
- FetchType.EAGER (즉시 로딩) : 연관된 엔티티를 즉시 로드
- mappedBy
- 양방향 관계에서 주인을 설정. 주인이 아닌 곳은 읽기 전용.
- 값 : 반대쪽 엔티티에서 관계를 설정한 필드명
@JoinColumn (외래 키 설정)
관계를 나타내는 외래키를 직접 설정할 때 사용한다.
주요속성
- name:
- 외래 키 컬럼 이름을 지정.
- 기본값: 연관된 엔티티 이름 + _ + 기본 키 컬럼 이름.
- referencedColumnName:
- 외래 키가 참조할 대상 엔티티의 컬럼 이름.
- 기본값: 대상 엔티티의 기본 키 컬럼.
- nullable:
- 외래 키가 null을 허용할지 여부.
- 기본값: true (null 허용).
- unique:
- 외래 키에 유니크 제약 조건 설정 여부.
- 기본값: false.
- insertable, updatable:
- 외래 키 값의 변경 가능 여부를 설정.
- 기본값: true.
@JoinTable (중간 테이블 설정)
다대다 (n:m) 관계에서 중간 테이블 정의할 때 사용한다.
주요속성
- name:
- 중간 테이블의 이름.
- 기본값: 엔티티1_엔티티2.
- joinColumns:
- 현재 엔티티와 연결된 외래 키 정보를 설정.
- @JoinColumn 사용.
- inverseJoinColumns:
- 반대쪽 엔티티와 연결된 외래 키 정보를 설정.
- @JoinColumn 사용.
fetch ( 로딩 방식 )
연관계의 엔티티 로딩 방식을 결정한다.
- etchType.LAZY:
- 실제로 엔티티를 사용할 때 데이터베이스에서 로드합니다.
- 성능 최적화에 유리하며, 대부분의 연관관계에서 기본값.
- FetchType.EAGER:
- 엔티티를 조회할 때 연관된 엔티티도 함께 로드합니다.
- 즉시 로딩은 성능 상의 문제를 유발할 수 있으므로 지양하는 것이 좋습니다.
cascade ( 전이 )
부모 엔티티 작업이 연관된 엔티티로 전파되는 방식을 정의한다.
- CascadeType.PERSIST: 부모 엔티티 저장 시 자식 엔티티도 저장.
- CascadeType.MERGE: 부모 엔티티 병합 시 자식 엔티티도 병합.
- CascadeType.REMOVE: 부모 엔티티 삭제 시 자식 엔티티도 삭제.
- CascadeType.REFRESH: 부모 엔티티 새로 고침 시 자식 엔티티도 새로 고침.
- CascadeType.DETACH: 부모 엔티티가 detach(영속성 컨텍스트에서 분리)되면 자식 엔티티도 detach.
- CascadeType.ALL: 위의 모든 작업 전파.
orphanRemoval ( 고아 객체 제거 )
- 부모 엔티티에서 연관관계가 제거된 자식 엔티티를 자동으로 삭제한다.
- orphanRemoval = true 설정 시 활성화된다.
- CascadeType.REMOVE와 자주 함께 사용된다.
처음만난 팀원들과 간단한 자기소개를 한뒤 프로젝트 설계에 바로 들어갔다. 심화과정은 기간이 짧아 생각보다 많이 타이트한 것 같다. 기능명세서, API 설계, ERD , 인프라 설계도 까지 하루만에 작성은 처음이다.
다른 분들은 프로젝트 경험이 많은 것 같아 내가 많이 부족할까 걱정이다. 늘 그렇듯 개발을 하다보면 멘탈이 터지는 일이 생길거고 악바리 근성으로 완수해낼거라 생각한다.
나는 성공한 프로젝트가 하나도 없는 사람이다.
이번에는 꼭 프로젝트를 끝까지 완수해보고싶다. 그리고 내가 어느정도로 남들과 협업을 하면서 개발을 할 수 있는 사람인지도 알고싶다. 이 과정이 끝날때 즈음엔 자신감을 가지고 좀 더 큰 시각으로 개발을 바라볼 수 있으면 좋겠다.
간단하게만 사용해본 docker 와 jenkins를 사용해 배포를 시도해보자 의견을 냈다.
물론 시간이 부족하면 그냥 배포할 수 있지만 이왕하는 거 어려운 상황속에서 도전을하는게 모두에게 도움이 될거라 생각한다. 무리한 도전이면 빠르게 다른 선택을 해야할 거 같다.
개발보다 설계가 더 괴로운건 모두가 같은 마음인 거 같다..
'Spring Boot' 카테고리의 다른 글
25.02.25 통합테스트 DB 환경 분리 (0) | 2025.02.25 |
---|---|
25.02.20 JWT 리팩토링 과 헥사고날 아키텍처 도입 (0) | 2025.02.20 |
25.02.19 QueryDSL (1) | 2025.02.19 |
25.02.17 JWT 검증 필터 와 테스트 코드 any() (0) | 2025.02.17 |
25.02.13 Spring Boot AOP (0) | 2025.02.13 |