JPA 기본 및 DB relation (1)

HEYDAY7·2022년 11월 20일
0

서버 관련 Background

목록 보기
3/10
post-thumbnail

시작하며

내가 JPA에 대해 너무 간략하게 만 생각하고 공부 및 프로젝트를 시작했던 거 같아서 한번이라도 제대로 훑고 가기 위해서 이를 적는다.

이 내용은 김영한 님의 저서 「자바 ORM 표준 JPA 프로그래밍」의 내용을 담고 있습니다.

JPA란

JPA 이전

JPA 이전, 즉 JPA가 없는 상황에서는 SQL문을 직접 써가면서 서버 코드를 짰었다.(RDB 기준) Table에 넣기 위해서 insert 코드를 짜고, 조회를 위해서 select와 join을 하고 말이다.

JPA는 개발자가 SQL문을 직접 작성할 필요없이 JPA가 제공하는 API를 사용하면 된다.

또한 기존의 SQL 문으로는 표현하기 애매했던 연관관계 매핑을 ORM 식으로 지원해준다.

JPA의 특징

아직 내가 직접적으로 다 느껴보진 못했지만 이런 특징들이 있다고 한다.

  • 생산성 향상
    지루하고 반복적인 INSERT와 같은 SQL을 대신 작성해줌.
    또 객체 설계 중심으로의 역전(기존은 데이터베이스 중심)

  • 유지보수
    위 생산성 향상과 맞물려 Entity의 필드 추가, 수정, 조회 등을 JPA가 대신 처리해줌으로 애초에 코드 수가 줄어든다. 따라서 관리해야하는 코드 수도 줄어든다.

  • 패러다임 불일치 해결 (SQL로만 써보지 않아 체감은 못해봄)
    상속, 연관관계, 객체 그래프 탐색, 비교하기 같은 불일치 해결

  • 성능 최적화

JPA 내부 구조 및 구현

엔티티, 엔티티매니저, 영속성 컨텍스트, flush 등 영속성(Persist)를 핵심으로 하는 여러 logic들이 있다.

Entity 매핑

Entity를 매핑시키고 코드를 쓸때 여러 annotation들을 사용한다.

  • @Entity : JPA를 사용해서 테이블과 mapping 하기 위해서 붙여줘야 한다.
  • @Table : 연관된 Table을 명시적으롤 지정해준다.
  • @Column : field에 붙이며 해당 column 설정
  • @Enumerated : enum 타입 field mapping
  • @Temporal : 날짜 타입 field mapping
  • @Transient : 특정 필드를 DB에 매핑하지 않는다.
  • @Access : JPA가 엔티티에 접근하는 방식 지정(?)

기본 키 매핑

우선 @Id annotation을 통해 key임을 선언하고, @GeneratedValue를 사용하면 자동 생성을 시킬 수 있다. 지금은 자세히 알 필요까진 없어보고 정리만 해두고 넘어간다.
해당 자동 생성에는 일반적으로 3가지 전략이 존재한다.

IDENTITY

기본 키 생성을 DB에 위임하는 전략
(주로 MySQL, PostgreSQL, SQL Server, H2에서 사용)

SEQUENCE

유일한 값을순서대로 생성하는 특별한 데이터베이스 오브젝트
(오라클, PostgreSQL, H2에서 주로 사용)

TABLE

특이하게 키 생성 전용 테이블을 만들어 사용. Table을 활용하기에 모든 DB에서 적용할 수 있다.

AUTO 전략

앞서 말한 3가지 중 DB에 따라 하나를 자동으로 선택해준다.

연관관계 매핑

@OneToOne, @OneToMany, @ManyToOne, @ManyToMany

@JoinColumn : 외래 키(foreign key) 매핑에 사용된다.
자세히 뜯어다보면 이렇다. @JoinColumn에는 name, referencedColumnName 이렇게 두가지 핵심(주) 파라미터가 있다.

  • name : 매핑할 외래 키 이름이다. 기본값을 필드명_[상대 필드의 pk column 명]
  • referencedColumnName : 외래 키가 참조하는 대상 테이블의 컬럼 명. 기본 값은 상대 필드의 pk column 명

단방향

단방향 mapping의 경우 1:N, N:1에 맞춰 @OneToMany, @ManyToOne을 잘 해주면 된다. 어렵지 않으므로 패스

양방향

핵심은 이 양방향이다. 양방향 연관관계의 경우 주인(Owner)가 필요하다. 해당 주인 쪽에서만 외래 키를 관리할 수 있고, 상대쪽은 읽기만 할 수 있다.

mappedBy 속성

mappedBy를 통해 주인관계를 설정한다. mappedBy를 사용하지 않는 쪽이 주인이 된다. 여기서 알아둬야할 점은 @ManyToOne과 @OneToMany annotation 중 후자만이 mappedBy 속성이 있기에 @ManyToOne annotation 쪽이 항상 연관관계의 주인이 된다.
mappedBy의 값은 연관관계의 주인을 지정한다.(테이블의 외래 키가 존재하는 곳을 지정해야 한다.)

정리

  1. @ManyToOne이 정의된 쪽이 연관관계의 주인
  2. @OneToMany의 mappedBy를 통해서 외래 키의 위치를 지정
  3. 연관관계의 생성은 ManyToOne 쪽에서!!

마치며

이번 글에서는 여기까지이다. 애매하게 알고 있던 JPA나 Entity relation과 관련해서 정보를 얻고가니 마음이 후련한다.
다음 글에서는 프록시와 spring data JPA를 짤막하게 알아본다.

profile
(전) Junior Android Developer (현) Backend 이직 준비생

0개의 댓글