JPA 엔티티 매핑 - 객체와 테이블 매핑, 데이터베이스 스키마 자동 생성

2022. 6. 29. 23:50·공부/JPA
반응형

출처 : 자바 ORM 표준 JPA 프로그래밍 인프런 강의

 

JPA 게시글은 대부분 인프런의 김영한님의 강의인 '자바 ORM 표준 JPA 프로그래밍' 기반으로 내용을 정리했습니다.

 

객체와 테이블 매핑

대표적인 엔티티 매핑

  • 객체와 테이블 매핑 : @Entity, @Table
  • 필드와 컬럼 매핑 : @Column
  • 기본 키 매핑 : @Id
  • 연관관계 매핑 : @ManyToOne, @JoinColumn

 

@Entity

  • @Entity가 붙은 클래스는 JPA가 관리하며 엔티티라 한다.
  • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity가 필수이다.
  • 주의!
    • 기본 생성자가 필수(접근제한자는 public 또는 protected 생성자)
    • final 클래스, enum, interface, inner 클래스 사용 불가
    • 저장할 필드에 final 사용 불가

JPA는 엔티티 객체를 생성할 때 기본 생성자를 사용한다. 그러므로 기본 생성자가 필수인데.. 자바에서는 생성자가 하나도 없으면 컴파일 시 기본 생성자를 자동으로 생성한다.

public Member() { }

 

생성자가 하나도 없으면 기본 생성자를 자동으로 생성한다. 이 말은 생성자가 하나라도 있으면 자동 생성을 해주지 않는다는 말이기도 하다.

@Id // PK
private Long id;
private String name;

public Member() { } // 기본 생성자

public Member(Long id, String name) {
    this.id = id;
    this.name = name;
}

 

@Entity에는 name이라는 속성이 있는데 JPA에서 사용할 엔티티의 이름을 지정하며 생략 시 클래스 이름을 그대로 사용한다. name을 꼭 줘야하는 상황이 아니라면 가급적 기본값을 사용하는게 좋다.

@Entity(name = "Member") 
public class Member {
}

 

@Table

엔티티와 매핑할 테이블을 지정한다.

  • name : 매핑할 테이블 이름(기본값은 엔티티 이름)

name의 경우는 데이터베이스의 Member 테이블의 이름이 Member가 아니라 MBR이라는 이름으로 테이블이 생성되어있다면 name 속성에 그 이름을 적어주면 그 테이블과 매핑되고 쿼리가 나갈 때 FROM절에 name 속성으로 설정된 값으로 세팅된다.

@Table(name = "MBR")

// 쿼리 로그
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_ 
    from
        MBR member0_ 
    where
        member0_.id=?
  • catalog : 데이터베이스 catalog 매핑
  • schema : 데이터베이스 schema 매핑
  • uniqueConstraints : DDL 생성 시에 유니크 제약 조건 생성

 


 

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

애플리케이션 실행 시점에 CREATE문으로 테이블을 생성을 할 수 있다. 즉, 테이블 중심이 아니라 객체 중심으로 개발을 할 수 있다. 그리고 저번 포스팅에서 JPA 특징 중 하나가 상용 DBMS별로 데이터 타입이나 함수 등의 명칭 차이를 설정만하면 알아서 맞춰주기 때문에 그에 맞는 적절한 DDL을 생성하며, 이렇게 생성된 DDL은 개발 장비에서만 사용된다. 운영 서버에서는 사용하지 않거나, 적절하게 추가적으로 다듬은 후에 사용한다.

  • hibernate.hbm2ddl.auto 속성. persistence.xml에서 설정해 줄 수 있다.
    • create - 기존 테이블 삭제 후 다시 생성(DROP + CREATE)  
    • create-drop - create와 같으나 종료 시점에 테이블을 DROP한다. (CREATE + DROP) 주로 테스트 케이스에서 많이 사용한다.
    • update - 변경분만 반영한다.(운영 DB에서 사용 금지)
    • validate - 엔티티와 테이블이 정상 매핑이 되었는지 확인한다.
    • none - 사용하지 않는다.

 

  • persistence.xml에서 옵션 넣기
<property name="hibernate.hbm2ddl.auto" value="속성값" />
  • create 속성 시 로그
Hibernate: 
    
    drop table Member if exists
Hibernate: 
    
    create table Member (
       id bigint not null,
        name varchar(255),
        primary key (id)
    )
  • create-drop 속성 시 로그
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.name as name2_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
Hibernate: 
    
    drop table Member if exists
  • update 속성 시 로그
<!-- 
속성을 update로 변경 후 실행해준다.
그리고 필드를 하나 추가한 후 다시 실행한다.	
-->

@Id
private Long id;
private String name;
private int age; <!-- age 필드 추가 -->

<!-- update 로그 -->
Hibernate: 
    
    alter table Member 
       add column age integer not null
Hibernate: 
    select
        member0_.id as id1_0_0_,
        member0_.age as age2_0_0_,
        member0_.name as name3_0_0_ 
    from
        Member member0_ 
    where
        member0_.id=?
        
<!-- drop 후 다시 생성하는 것이 아니라 alter로 테이블을 수정한다. -->

주의할 점은 필드를 추가하는 것만 인식하지 삭제하는 건 인식하지 못해서 ALTER 쿼리가 생성되지 않는다.

  • validate 속성 시 로그
// 임의의 필드를 하나 추가한다.

@Id // PK
private Long id;
private String name;
private int test;

// 실행하면 test 필드가 테이블에 없다는 에러가 발생한다.
Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: hello] Unable to build Hibernate SessionFactory
..생략
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing column [test] in table [Member]
..생략
  • none
    • 이 기능을 사용하고 싶지 않을 때의 속성값이다. 
    • 사실 none이 내포하고 있는 의미는 없다. 'tefdsfa'의 값을 적어도 none과 똑같이 적용된다. 즉 기능이 있는 속성 외에 다른 아무 속성을 넣으면 이 옵션이 설정되지 않는다. 참고로 주석처리를 해도 실행되지 않아 none과 똑같은 결과를 가져온다.

 

  • 주의할 점!
    • 운영 장비에는 절대 create, create-drop, update를 사용하면 안된다.
    • 개발 초기 단계는 create 또는 update
    • 테스트 서버는 update 또는 validate -> create를 사용하면 데이터가 다 날라가서 문제!
    • 스테이징과 운영 서버는 validate 또는 none

 

DDL 생성 기능

  • 제약 조건을 추가할 수 있다.
@Id // PK
private Long id;

@Column(nullable = false, unique = true, length = 10)
private String name;

DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA 실행 로직에는 영향을 주지 않는다.

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/JPA' 카테고리의 다른 글
  • JPA 엔티티 매핑 - 기본 키 매핑
  • JPA 엔티티 매핑 - 필드와 컬럼 매핑
  • JPA 영속성 관리 - 내부 동작 방식 준영속 상태
  • JPA 영속성 관리 - 내부 동작 방식 플러시
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    JPA
    전자정부프레임워크
    코딩테스트
    에러해결
    프론트엔드
    프로그래머스
    SQL
    개발자
    스프링부트
    MSA
    springboot
    방통대
    IT
    oracle
    react
    알고리즘
    기출문제
    RESTful
    운영체제
    백준
    Spring
    Java
    넥사크로
    egov
    토이프로젝트
    자바스크립트
    인프런
    SpringBoot를 이용한 RESTful Web Service 개발
    QueryDSL
    토비의스프링부트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
JPA 엔티티 매핑 - 객체와 테이블 매핑, 데이터베이스 스키마 자동 생성
상단으로

티스토리툴바