[자바 ORM 표준 JPA 프로그래밍] 4. 엔티티 매핑

2022. 5. 13. 01:53Web/Spring

반응형

velog에서 옮겨온 글 입니다.

원본 날짜: 2022-03-15T20:21:32.425Z

 

김영한님의 '자바 ORM 표준 JPA 프로그래밍' 서적을 읽고 정리한 글 입니다.

객체와 테이블 매핑

@Entity

  • JPA가 관리하는 객체. (엔티티)
  • JPA를 사용해서 테이블과 매핑할 클래스는 필수로 붙여야 한다.

주의사항

  • 기본 생성자를 필수로 구현해야 한다. (파라미터가 없는 public 또는 protected 생성자)
  • final 클래스, enum, interface, inner 클래스에 사용할 수 없다.
  • DB 저장할 필드에는 final을 사용할 수 없다.

@Table

  • 엔티티와 매핑할 테이블을 지정한다.
  • 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.

데이터베이스 스키마 자동 생성

  • JPA는 DB 스키마를 자동으로 생성하는 기능을 지원한다.
  • 애플리케이션 실행 시점에 DB 테이블이 자동으로 생성되므로 개발자가 테이블을 직접 생성하는 수고를 덜 수 있다.

하지만 스키마 자동 생성 기능이 만든 DDL은 완벽하지 않으므로 개발 환경에서 사용하거나 매핑을 어떻게 해야하는지 참고하는 정도로만 사용하는 것이 좋다.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
    <persistence-unit name="jpabook">
        <class>jpabook.model.Member</class>
        <class>jpabook.model.Item</class>
        <class>jpabook.model.Order</class>
        <class>jpabook.model.OrderItem</class>
        <properties>
            <!-- 필수 속성 -->
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
            <property name="javax.persistence.jdbc.user" value="sa"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
            <!-- 옵션 -->
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.use_sql_comments" value="true" />
            <property name="hibernate.id.new_generator_mappings" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            <property name="hibernate.physical_naming_strategy" value="org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy"/>
        </properties>
    </persistence-unit>
</persistence>

운영 서버에는 절대 create, create-drop, update 를 사용하면 안된다.

  • 개발 초기 단계에는 create or update
  • 테스트 서버는 update or validate
  • 스테이징과 운영 서버는 validate or none

이름 매핑 전략을 속성으로 바꿀 수 있다. 다만, hibernate5 부터는 hibernate.ejb.naming_strategy 대신 hibernate.physical_naming_strategy 를 사용한다.

DDL 생성 기능

  • DDL을 자동으로 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.
  • 그래도 개발자가 엔티티만 보고도 다양한 제약 조건을 확인할 수 있는 장점이 있다.

기본 키 매핑

직접 할당

  • @Id 만 사용한다.

IDENTITY 전략

  • @GeneratedValue(strategy = GenerationType.IDENTITY) 를 사용한다.
  • 기본 키 생성을 DB에 위임한다.
  • 주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용한다.
  • JPA는 IDENTITY 전략에서만 em.persist() 로 호출하자 마자 바로 insert 쿼리를 날린다.
  • JDBC 드라이버에 insert 쿼리 직후 바로 리턴을 받을 수 있는 기능이 있어서, id 조회 때는 select 쿼리를 날리지 않는다.

SEQUENCE 전략

  • @GeneratedValue(strategy = GenerationType.SEQUENCE) 를 사용한다.
  • DB에 시퀀스 오브젝트를 만들어서 이 값을 통해 기본 키를 생성한다.
  • Oracle, PostgreSQL, DB2, H2에서 사용할 수 있다.
  • JPA는 전략이 SEQUENCE면 값을 DB에서 먼저 가져온다. 그래서 em.persist() 시점에 id를 조회할 수 있는 것이다.
  • allocationSize 를 사용하면 여러 데이터를 이어서 em.persist() 하면서 next value를 call 하는 대신, 기본값 N개를 메모리 상에 일단 준비해놓고 거기서 사용한다. 다 쓰고 다시 call 하면 그 다음 N개를 가져온다.

TABLE 전략

  • 키 생성 전용 테이블을 만들어서 데이터베이스 시퀀스를 흉내내는 전략이다.
  • 장점: 모든 데이터베이스에 적용할 수 있다.
  • 단점: 테이블이 따로 생기다보니 락이 걸리는 등 성능이 좋지 않다.

AUTO 전략

  • DB 방언에 따라 위 3가지 전략중에서 하나를 자동으로 선택하는 전략이다.
  • @GeneratedValue 의 기본값이다.
  • 예를 들어 Oracle은 SEQUENCE를, MySQL은 IDENTITY를 사용한다.
  • 키 생성 전략이 아직 확정되지 않은 개발 초기 단계나 프로토타입 개발 시 사용 가능하다.

권장하는 식별자 선택 전략

  • 자연 키보다는 대리 키를 권장한다. (ex. 오라클 시퀀스, auto_increment, 키생성 테이블)
  • JPA는 모든 엔티티에 일관된 방식으로 대리 키 사용을 권장한다.
반응형