Spring Boot: JPA 적용기 - entity 구현

2024. 9. 24. 21:10Spring Boot/JPA

728x90
반응형

#0. 개요

  • 기존 mybatis 로 되어있는 코드를 JPA 로 점진적 변환
    • 간단한 CRUD 등 코드에 너무 많은 시간 소요하지 않기 위함.
  • JDBC (Java Database Connectivity)
    • DB에 접근하기 위한 자바 표준 인터페이스
    • 복잡함. 예외처리, connection 사용 후 반환을 개발자가 직접해야함
    • SQL mapper, ORM 은 위 과정들을 추상화시켜 제공하는 방식.
  • SQL mapper
    • 객체와 SQL 문 질의 결과를 매핑.
    • SQL 문을 직접 작성
  • ORM
    • 객체와 RDB 데이터 매핑
    • JPA
      • ORM 기술에 대한 표준 API
      • 장점
        • 개발자의 SQL 중심 개발 → 객체 중심 개발
      • JPQL (java persistence query language)
        • 테이블이 아닌 객체를 통해 쿼리 작성
  • hibernate
    • JPA의 구현체
    • JPA 자체는 인터페이스와 같다

#1. entity 작성

@Table(name = "테이블 명", schema = "##schema##")

  • 스키마는 멀티테넌트이기에, token 에 따라 다르게끔 설정
  • entity 마다 테이블명 설정

1) 기본 컬럼

  • @Comment
    • 컬럼 한글명
  • @Column
    • 실제 디비내 이름
    • length
      • 기본값 255로 되어있음
      • varchar 등의 길이 설정
    • precision
      • numeric 앞자리
    • scale
      • numeric 뒷자리

2) PK

  • @Id
    • PK 인 거를 명시
  • @GeneratedValue(strategy = GenerationType.*IDENTITY*)
    • autoIncrement PK 보장

3) 조인컬럼

  • @JoinColumn
    • 조인컬럼이라는 것을 명시
      • 두 테이블 간의 외래키 관계 설정
    • 여기는 조인이 되는 객체가 FK의 주인 객체
      • 즉 참조 되는 쪽
    • FK를 가지고 있는 쪽에서 명시
      • @ManyToOne 이랑 사용
  • @OneToOne
    • 1대1 관계
  • @ManyToOne
    • FK 를 가지고 있는 쪽
  • @OneToMany
    • 기저가 되는 데이터 쪽
    • 얘를 FK로 참조하고 있는 entity 의 리스트를 가지고 있음
      • 예) 카드사 쪽에서 법인카드 리스트를 가지고 있음
    • 양쪽으로 가고 싶을 때 추가
      • 양방향 관계 참조
      • 즉 필수가 아님
    • 여기나 @OneToOne 쪽에만 mappedBy를 쓸 수 있음

위 조인 컬럼에서 사용할 수 있는 옵션

  • mappedBy
    • 연관관계의 주인을 설정
      • 해당 주인만이 외래 키를 관리(등록, 수정)
        • 주인 쪽은 mappedBy 지정 X
      • 주인이 아닌 쪽은 읽기만 가능
        • 주인 아닌 쪽이 mappedBy 로 주인 지정
      • 주인은 외래 키가 있는 쪽임.
        • 즉 주인이 아닌 쪽에서 주인이 누군지 설정해주는 옵션
    • FK를 참조 당하는 쪽에서의 세팅
  • optional- 연관 관계의 필수 여부
    • false
      • inner join
      • 관계가 반드시 존재
    • true - 기본값
      • outer join
      • 관계가 선택적인지를 지정
  • fetch- 연관 관계의 대상을 가져올 때 어떻게 가져올 지
    • FetchType.LAZY (지연로딩)
      • 연관된 엔티티가 실제로 접근될 때 로딩.
      • 모든 연관관계는 우선 이걸로 적용 (fetch join)
    • FetchType.FETCH
      • 연관된 엔티티가 함께 로딩
  • cascade - 부모 엔티티에 대한 작업이 자식 엔티티에도 적용.
    • PERSIST: 부모 엔티티가 저장될 때, 자식 엔티티도 함께 저장.
    • MERGE: 부모 엔티티가 병합될 때, 자식 엔티티도 함께 병합.
    • REMOVE: 부모 엔티티가 삭제될 때, 자식 엔티티도 함께 삭제.
    • REFRESH: 부모 엔티티가 새로고침될 때, 자식 엔티티도 함께 새로고침.
    • DETACH: 부모 엔티티가 영속성 컨텍스트에서 분리될 때, 자식 엔티티도 함께 분리.
    • ALL: 모든 작업이 자식 엔티티에 전파.
  • orphanRemoval
    • true
      • 부모 객체가 삭제될 때 자식 객체가 같이 삭제 될 지 결정
  • 예시:
@OneToMany(mappedBy = "vbrItem", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
@Builder.Default
private List<VbrSelItem> vbrSelItemList = new ArrayList<>();
  • insertable
    • 해당 필드가 INSERT SQL 문에 포함될 지 여부 지정
    • true
    • false
  • updatable
    • 해당 필드가 UPDATE SQL 문에 포함될 지 여부 지정
    • true
    • false
  • 만약 조인 컬럼과 FK 컬럼을 따로 entity 에서 구현할 경우, 한 쪽은 위 두 옵션을 false 로 설정해야함.
  • 예시:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "tmplt_sectn_sbt_id", insertable = false, updatable = false)
private VtmTmpltSectn vtmTmpltSectn;

4) 양방향 관계

https://colevelup.tistory.com/41

  • 객체의 양방향 관계
    • 연결되는 각 객체에서, 서로로 향하는 단방향 관계 2개라고 보는 것이 타당.
    • 1대1인 경우
      • @OneToOne 2개
    • 1대다 인 경우
      • @ManyToOne
        • FK를 가지는 쪽
        • Fetch 전략 등 사용
      • @OneToMany
        • 기저가 되는 데이터 쪽
        • mappedBy를 사용
  • 객체의 단방향 관계
    • 단방향쪽으로 최대한 설계하는 것이 좋음
      • 코드가 간결함.
        • 양방향에서는 양쪽 모두 관리
      • 메모리 사용량 저하
      • 성능
entity 작성 과정:
1. 테이블과 똑같이 속성 구현 (column, comment, length 설정)
2. FK를 가지는 쪽 테이블에서 ManyToOne 컬럼 설정.
	2-1. FK의 주인 테이블의 엔티티 타입으로 속성추가
	2-2. cascade, fetch, optional 전략 설정
	2-3. JoinColumn 어노테이션 추가하여 FK 명시
3. 기저 데이터 쪽에서 OneToMany 컬럼 설정.
	3-1. 만약 단방향 관계만 유지하고 싶으면 컬럼 설정 X
	3-2. mappedBy 로 연관관계 주인 컬럼 설정
	3-3. 연관관계 주인은 ManyToOne 컬럼이 걸린 속성명 (보통 OneToMany 속성의 클래스명과 동일)
	3-4. cascade, fetch, orpanRemoval 전략 설정
728x90
반응형