2.4 객체 매핑 시작

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package ~~~
import javax.persistence.*;

@Entity
@Table(name = "MEMBER")
public class Member { 
    @ID
    @Column(name = "ID")
    private String id;
    
    @Column (name = "NAME")
    private String username;
    
    // 매핑 정보가 없는 필드
    private Integer age;   
}

SCR-20240828-pbww

SCR-20240828-opqk

  • @Entitiy

    • 이 클래스를 테이블과 매핑한다고 JPA에게 알려줌
    • @Entitiy가 사용된 클래스를 엔티티 클래스라 한다.
  • @Table

    • 엔티티 클래스에 매핑할 테이블 정보를 알려준다.
    • 이 어노테이션을 생략하면, 클래스 이름을 테이블 이름으로 매핑한다.
  • @Id

    • 엔티티 클래스의 필드를 테이블의 기본 키(Primary Key) 에 매핑
    • @Id 가 사용된 필드를 식별자 필드라 한다.
  • @Column

    • 필드를 컬럼에 매핑
  • 매핑 정보가 없는 필드

    • 매핑 어노테이션을 생략하면 필드명을 사용해서 컬럼명으로 매핑한다.

2.5 속성 설정

주로 사용하는 속성

SCR-20240828-ordmSCR-20240828-osbo

Spring Boot에서 JPA를 사용하는 경우, persistence.xml 파일은 꼭 필요하지 않습니다. Spring Boot는 persistence.xml 파일 없이도 애플리케이션을 설정하고 동작할 수 있도록 자동 설정 기능을 제공합니다.

대신, Spring Boot에서는 애플리케이션 속성 파일(application.properties 또는 application.yml)을 사용하여 JPA 관련 설정을 수행합니다.

Spring Boot는 @SpringBootApplication 애노테이션을 통해 자동으로 JPA 관련 설정을 감지하고, 별도의 persistence.xml 파일 없이도 애플리케이션을 구성합니다

persistence.xml이 필요한 경우

일반적으로 Spring Boot와 JPA를 사용할 때 persistence.xml은 필요하지 않지만, 다음과 같은 특정한 경우에는 사용할 수 있습니다

  • 기존의 전통적인 JPA 설정을 그대로 유지해야 할 때
  • 복잡한 JPA 설정이나 여러 개의 영속성 유닛을 설정해야 할 때
  • Spring Boot의 자동 설정을 우회하여 특정 설정을 수동으로 처리해야 할 때

2.5.1 데이터베이스 방언

SCR-20240828-oryf

SCR-20240828-orml

  • JPA는 특정 데이터베이스에 종속되지 않는다.

    • 다른 데이터베이스로 쉽게 교체 가능
    • 하지만, 각 데이터베이스가 제공하는 SQL 문법과 함수가 다를 수 있다.
  • SQL 표준을 지키지 않거나 특정 데이터베이스만의 고유한 기능을 JPA에서는 방언(Dialect) 이라 한다.

  • JPA 구현체들은 다양한 데이터베이스 방언 클래스를 제공한다.

2.6 애플리케이션 개발

SCR-20240828-osta

2.6.1 엔티티 매니저 설정

엔티티 매니저 팩토리 설정

  • JPA를 시작하려면 설정 정보를 사용해서 엔티티 매니저 팩토리를 생성해야 한다.
  • 설정 정보를 읽어서 JPA를 동작시키기 위한 기반 객체를 만들고 JPA 구현체에 따라서는 데이터베이스 커넥션 풀도 생성
    • 따라서, 엔티티 매니저 팩토리를 생성하는 비용은 아주 크다.
    • 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 한다.
  • val emf = Persistence.createEntityManagerFactory("~~~")

엔티티 매니저 생성

  • 엔티티 매니저 팩토리에서 엔티티 매니저를 생성한다.
  • JPA의 기능 대부분은 이 엔티티 매니저가 제공한다.
    • 대표적으로 엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.
  • 엔티티 매니저는 내부에 데이터베이스 커넥션를 유지하면서 데이터베이스와 통신한다.
  • 따라서 애플리케이션 개발자는 엔티티 매니저를 가상의 데이터베이스로 생각할 수 있다.
  • val em = emf.ceateEntityManager()

종료

  • 사용이 끝난 엔티티 매니저는 반드시 종료해야 한다.

    • em.close()
  • App이 종료할 때 엔티티 매니저 팩토리도 종료해야 한다.

    • emf.close()

2.6.2 트랜잭션 관리

SCR-20240828-ovdw-2

  • JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 한다. 트랜잭션 없이 데이터를 변경하면 예외가 발생한다.
  • 트랜잭션을 시작하려면 엔티티 매니저에서 트랜잭션 API를 받아와야 한다.

2.6.3 비즈니스 로직과 JPQL

SCR-20240828-oznj

  • JPA를 사용하면 애플리케이션 개발자는 엔티티 객체를 중심으로 개발하고 데이터베이스에 대한 처리는 JPA에 맡겨야 한다.

    • 등록, 수정, 삭제, 한 건 조회는, SQL을 전혀 사용하지 않아도 된다.

    • 문제는 검색 쿼리다. JPA는 엔티티 객체를 중심으로 개발하므로 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색해야 한다.

그런데 테이블이 아닌 엔티티 객체를 대상으로 검색하려면 데이터베이스의 모든 데이터를 애플리케이션으로 불러와서 엔티티 객체로 변경한 다음 검색해야 하는데, 이는 사실상 불가능하다.

  • 결국 검색 조건이 포함된 SQL을 사용해야 한다. JPA는 JPQL(Java Persistence Query Language) 이라는 쿼리 언어로 이를 해결한다.

  • JPA는 SQL을 추상화한 JPQL이라는 객체지향 퀴리 언어를 제공

  • JPQL은 엔티티 객체를 대상으로 쿼리한다. 쉽게 이야기해서 클래스와 필드를 대상으로 쿼리한다.

    • select m from Member m 이 바로 JPQL 이다.

    • from Member는 MEMBER 테이블이 아니라, Member 엔티티 객체를 말한다.

    • JPQL은 데이터베이스 테이블을 전혀 알지 못한다.

  • JPA는 JPQL을 분석해서 다음과 같은 적절한 SQL을 만들어 데이터베이스에서 데이터를 조회한다.

    • SELECT M.ID, M.NAME, M.AGE FROM MEMBER M

Reference