JPA(Java Persistence API)

mangez_js·2024년 6월 4일

Study

목록 보기
1/47

JPA(Java Persistence API)

Java에서 객체를 데이터베이스에 저장하고 관리하기 위한 인터페이스와 기능을 제공하는 API
ORM(Object Relational Mapping)

  • 객체와 DB의 데이터를 "자동으로 매핑" 시켜주는 프레임워크

JPA 장점
1. 특정 데이터베이스 종속되지 않음
2. SQL문이 아닌 Method를 통해 DB를 조작할 수 있어, 개발자는 객체 모델을 이용하여 비즈니스 로직을 구성하는데만 집중할 수 있다.
3. 객체 지향적 프로그래밍 및 생산성 향상
4. 유지보수 측면에서 좋고 재사용성도 증가

JPA 단점
1. 복잡한 쿼리 처리 불가
2. 자동으로 생성되는 쿼리로 인해서 개발자가 의도하지 않는 성능 저하
3. 방대한 JPA 기술 학습에 필요한 시간과 노력

Spring Data JPA

Setting

  1. 의존성 추가

  2. DB Data Source 연결
    Spring Boot의 경우

    1. application.yaml에 설정한다
    2. dataSource
      1. spring.datasource.driver-class-name : JDBC 드라이버의 경로
      2. spring.datasoruce.url : DataBase 주소
      3. spring.datasource.username : 사용자 이름
      4. spring.datasource.password : 사용자 비밀번호
  3. Model, Repository, Service 패키지 생성

    Model/Entity

  • DB Table을 지정하는 Class 생성

    @Entity Annotation을 통해 Entity Class임을 선언

  • 클래스 이름을 지정
    1. 클래스 이름을 DB Table 이름과 동일하게 할 수 있다. 간단하고 직관적이다.
    2. 클래스 이름을 테이블 이름과 다르게 지정하려면 @Table(name="테이블 이름") Annotation을 사용하여 테이블 이름을 명시적으로 지정할 수 있다.
  • field를 생성한다.
    • 엔티티 클래스의 필드는 DB Table의 열(Column)에 매핑된다.
      - Field의 이름과 Data 유형을 테이블의 열에 맞게 지정할 수 있다.
      • Field 이름과 열(Column)의 이름을 다르게 지정하려면 @Column Annotation의 name 속성으로 지정해 이름을 명시적으로 지정할 수 있다.
    • @Id Annotation을 통해 PK(Primary Key) Field에 대한 정의
      - 해당 필드는 엔티티의 고유 식별자로 사용
  • Getter / Setter 를 생성
    • Lombok 라이브러리를 사용하면 Getter와 Setter를 자동으로 생성할 수 있다.
      - @Data Annotation을 사용하면 @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 등을 한 번에 적용 할 수 있다.

JPA 동작원리

Entity Manager Factory(엔티티 매니저 인스턴스를 관리하는 주체)

  • Application 실행 시 한 개만 만들어짐
  • 사용자로부터 요청이 오면 엔티티 매니저를 생성

Entity Manager(Persistence Context에 접근하여 DB 작업을 제공하는 객체)

  • 내부적으로 DB Connection을 이용해서 DB에 접근

Persistence Context(Entity를 영구 저장하도록 지원하는 환경으로써 엔티티 매니저를 통해 접근 가능함)

Annotation

@Entity

엔티티 클래스를 지정하는 어노테이션, 이 어노테이션이 붙은 클래스는 JPA의 엔티티로 인식
EntityClass와 DB의 테이블을 매핑하기 위해 사용

  • name 속성
    - JPA에서 사용할 엔티티 이름 지정, 생략시(default) 클래스 이름을 엔티티 이름으로 지정

@Table

@Entity Annotation과 함께 사용되며 Entity Class와 매핑되는 DB Table의 정보를 설정하는 Annotation
테이블 명, 스키마 명 등을 지정할 수 있다.

  • 속성
    - name 속성

    매핑할 테이블 이름, 생략 시 엔티티 이름(@Entity(name="~")) 사용

    • catalog 속성
      catalog 기능이 있는 DB에서 catalog 매핑
    • schema 속성
      schema 기능이 있는 DB에서 schema 매핑
    • uniqueContraints 속성
      DDL 생성 시 유니크 제약조건 생성
      스키마 자동 생성 기능을 사용해 DDL을 만들 때만 사용

@Id

엔티티 클래스의 기본 키(primary key)를 지정하는 Annotation
@Id 어노테이션만 적게될 경우 기본 키 값을 직접 부여해줘야 한다.

@GeneratedValue

어노테이션을 사용하면 기본 값을 DB에서 자동으로 생성하는 전략을 사용 할 수 있다.

  • strategy 속성
    -GenerationType.IDENTITY : 기본 키 생성을 DB에 위임

    자동 증가(auto-increment) 열이나 IDENTITY 컬럼을 사용하여 새로운 엔티티의 기본 키 값을 생성

    - GenerationType.SEQUENCE : DB 시퀀스를 사용해서 기본 키 할당

    데이터베이스는 미리 정의된 시퀀스를 사용하여 각 엔티티에 대한 고유한 기본 키 값을 생성

    • GenerationType.TABLE : 키 생성 테이블 사용

      데이터베이스는 키 생성 테이블을 사용하여 각 엔티티에 대한 고유한 기본 키 값을 생성

    • GenerationType.AUTO : 선택된 DB에 따라 JPA 구현체가 자동으로 적절한 전략을 선택

@Column

엔티티 클래스의 필드와 데이터베이스 테이블의 열을 매핑하는 어노테이션

  • 속성
    -name 속성
    - 필드와 매핑할 테이블의 컬럼 이름 지정
    - default는 필드이름으로 대체
    • insertable 속성
      • Insert Query 명령 수행 시 field 값 저장 여부를 결정
        - true : 엔티티 저장 시 필드 값 저장
        - false : 필드 값이 저장되지 않음
    • updatable 속성
      • Update Query 명령 수행 시 field 값 수정 여부를 결정
        - true : 엔티티 수정 시 값이 수정
        - false : 엔티티 수정 시 값이 수정 되지 않음
    • table 속성
      • 하나의 엔티티를 두 개 이상의 테이블에 매핑할 때 사용
    • nullable 속성
      • null 값 허용 여부 설정
        - true : (default) null 제약 조건
        - false : not null 제약 조건
    • length 속성
      • 문자 길이 제약조건, String 타입일 때 사용
    • precision, scale 속성
      • BigDecimal 타입에서 사용
        • precision : 소수점을 포함한 전체 자릿수 설정
        • scale : 소수의 자릿수
    • unique 속성
      • DDL시 컬럼에 유니크 제약조건 부여
    • columnDefinition 속성
      • DDL시 데이터베이스 컬럼 정보를 직접 부여

@Transient

Entity Class의 Field를 DB의 테이블과 매핑되지 않도록 지정할 때 사용한다.
객체에 임시로 값을 보관하고 싶을 때 사용한다.

@Enumerated

Java Enum 타입을 매핑할 때 사용한다.

  • value 속성
    - EnumType.ORDINAL : enum 순서를 DB에 저장
    • EnumType.STRING : enum 이름을 DB에 저장

@Access

Entity Field에 접근하는 방식을 지정한다.

  • value 속성
    - AccessType.FIELD : 멤버 변수에 직접 접근
    • AccessType.PROPERTY : Getter/Setter 메소드를 통해 접근

@Temporal

날짜 타입을 매핑할 때 사용

  • value 속성
    - TemporalType.DATE : 날짜, DB date 타입과 매핑(ex: 2024-09-11)
    • TemporalType.TIME : 시간, DB time 타입과 매핑(ex: 16:39:12)
    • TemporalType.TIMESTAMP : 날짜와 시간 DB timestamp 타입과 매핑(ex : 2024-09-11 16:39:12)

@Lob

Large Object 필드를 매핑하는데 사용됩니다. 이는 데이터베이스에 대용량의 데이터를 저장하는데 사용
필드 타입이 문자열이라면 CLOB(Character Large Object), 나머지는 BLOB(Binary Large Object)을 매핑

@JoinColumn

연관 관계에서 조인 컬럼을 지정하는데 사용된다.
외래 키(Foreign Key)를 포함한 Join Column을 지정하여 두 Entity 간의 관계를 매핑한다.

Entity Life Cycle


비영속(new)

  • new 키워드를 통해 생성된 상태로 아직 영속성 컨텍스트에 저장되지 않음

영속(managed)

  • 엔티티가 영속성 컨텍스트에 저장되어 관리되는 상태
  • 아직 DB에 저장된 상태 X, 트랜잭션 Commit 후에 DB에 반영

준영속 상태(detached)

  • 영속성 컨텍스트에 엔티티가 저장되었다가 분리된 상태

삭제 상태(removed)

  • 영속성 컨텍스트와 데이터베이스에서 삭제된 상태

Persistence Context 사용 시 이점


1차 캐시

  • 따로 캐시 설정을 하지 않았지만 영속성 컨텍스트 내에서 자동으로 엔티티에 대해서 캐시 처리하는 것

동일성 보장

  • 하나의 트랜잭션에서 같은 키값으로 같은 엔티티 조회를 보장 받음


트랜잭션을 지원하는 쓰기 지연

  • entityManager.persist() 호출하면 1차 캐시에 저장과 동시에 지연 SQL 저장소에 저장
  • Commit 호출 시 쌓인 SQL문들이 flush() 되면서 DB에 반영
  • 한 번에 처리하기 때문에 성능 이점

변경 감지

  • JPA는 1차 캐시에 DB에서 처음 불러운 엔티티의 스냅샷을 저장
  • 스냅샷과 비교하여 변경 내용이 있다면 UPDATE SQL 수행

0개의 댓글