SpringBoot3 JPA hibernate ddl-auto 종류와 뜻 none, validate, update, create, create-drop

ddl-auto는 JPA의 기능으로 SpringBoot3 프로젝트가 실행될 때
DB 스키마를 어떻게 처리할지 정한다.
5개의 옵션이 있고, 개발편의에 따라 설정하며 사용하면 된다.
다만, 운영서버만큼은 사용을 자제하고
필요하다면 none 또는 validate만을 설정하여 사용하도록 한다.

ddl-auto 옵션 종류

springboot3 jpa hibernate ddl auto types and meanings
spring.jpa.hibernate.ddl-auto:
none, validate, update, create, create-drop

SpringBoot3에서 JPA를 사용할 때 ddl-duto 옵션을 사용할 수 있다.
이것은 SpringBoot3 프로젝트가 실행될 때 연동된 DB 스키마를 어떻게 처리할지에 대한 동작을 설정하는 옵션이다.
ddl-auto 옵션은 5가지 종류이며, `none, validate, update, create, create-drop`이 있다.
각각의 설정값에 따라 SpringBoot3 프로젝트가 실행될 때 JPA에 연동된 DB 스키마를 처리하게 된다.
주의할 점은 운영서버에 반영할 때이며, 옵션값을 `none` 또는 `valudate`로 설정하는 것을 추천한다.

ddl 뜻

옵션을 다루지 전에 `ddl`이 무엇인지 살펴보자.
`ddl`은 `Data Definition Language`의 앞글자를 딴 약어이다.
데이터의 구조와 형태를 정의하는 것을 의미한다.
흔히 DB의 테이블의 구조를 조작하는 명령어 정도로 생각하면 된다.
DB 테이블을 조작하는 명령어의 종류는 4가지이며,
각각 `CREATE, ALTER, DROP, TRUNCATE`가 있다.
이들의 기능을 간단히 살펴보면 다음과 같다.

  • CREATE TABLE
    • 테이블을 새롭게 만든다.
  • ALTER TABLE
    • 테이블을 구조를 변경한다.
  • DROP TABLE
    • 테이블을 완전히 삭제한다.
  • TRUNCATE TABLE
    • 테이블의 구조는 남기고, 데이터를 삭제하고 완전히 초기화한다.

spring.jpa.hibernate.ddl-auto 옵션 종류

SpringBoot3에서 JPA를 사용할 때 Entity를 사용하면 DB 테이블을 편하게 조작할 수 있다.
Entity는 DB 테이블과 1:1 매핑되어 백엔드(BackEnd)에서 CRUD를 할 수 있도록 도와준다.
Entity가 DB 테이블과 1:1 매핑된다는 점에서 `spring.jap.hibernate.ddl-auto`는 상당히 유용하다.
SpringBoot3 프로젝트가 실행될 때 DB 테이블을 자동으로 맞춰준다는 점에 있다.
Entity만 변경하면 DB 테이블 또한 변경할 수도 그대로 둘 수 있다.
상당히 편한 기능이다.
하지만, 주의할 점도 있는데 운영서버일 경우이다.
일단, `spring.jpa.hibernate.ddl-auto`옵션 5개와 동작은 다음과 같다.

  • none
    • 프로젝트 시작시
      DB 테이블 조작을 무시한다.
  • create
    • 프로젝트 시작시
      DB 테이블을 모두 삭제한 후
      Entity 기준으로 새롭게 DB 테이블을 만든다.
  • create-drop
    • 프로젝트 시작시
      DB 테이블을 모두 삭제한 후
      Entity 기준으로 새롭게 DB 테이블을 만들고,
      프로젝트 종료시 DB 테이블을 모두 삭제한다. 
  • update
    • 프로젝트 시작시
      DB 테이블을 Entity 클래스와 비교한 후
      차이가 있는 부분을 자동으로 변경한다.
      DB 테이블에 데이터가 있다면 삭제되지 않고, 유지된다.
  • validate
    • 프로젝트 시작시
      DB 테이블과 Entity 클래스와 비교한 후
      차이가 있다면, 예외를 발생시킨다.
      DB 테이블의 변경은 하지 않는다.

실제 동작 살펴보기

이제는 SpringBoot3 프로젝트를 생성한 후,
JPA를 이용해 `spring.jpa.hibernate.ddl-auto` 실제 동작을 살펴본다.
과정은 다음과 같다.
  1. SpringBoot3 프로젝트 생성하기
  2. JPA 라이브러리 설정하기
  3. build.gradle에 spring.jpa.hibernate.ddl-auto 옵션 설정하기
    1. none
    2. create
    3. create-drop
    4. update
    5. validate

SpringBoot3 프로젝트 생성하기

JPA 기능 중 ddl-auto 동작을 테스트하고, 확인해 보기 위해 
먼저 스프링부트3( SpringBoot3 ) 프로젝트를 생성한다.
여기서는 인텔리제이( IntelliJ )를 기준으로 하며, 설정은 다음과 같다.
프로젝트의 명칭과 경로는 자신이 원하는 것으로 변경해도 된다.

  • SpringBoot 프로젝트 정보
    • Name : 프로젝트 명칭
    • Location : 프로젝트 설치 경로
    • Language : Java
    • Type : Gradle - Groovy
    • Group : 그룹 명칭
    • Artifect : 식별 명칭
    • Package Name : 그룹 명칭 + 식별 명칭 ( 수정 가능 )
    • JDK : 버전 17
    • Java : 버전 17
    • Packaging : Jar
  • Dependency 의존성 외부 라이브러리
    • Lombok
      • Develper Tools > Lombok
    • Spring Web
      • Web > Spring Web
    • Thymeleaf
      • Template Engines > Thymeleaf

인텔리제이 새 프로젝트 설정

기본 의존성 ( Dependencies ) 추가하기

JPA 라이브러리 설정하기

ddl-auto 사용을 위해 SpringBoot3에 의존성을 추가해야 한다.
DB는 MySQL을 사용하도록 한다.

dependencies {
    .....

    /* JPA */
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    /* MySQL */
    runtimeOnly 'com.mysql:mysql-connector-j'
}

위의 의존성 추가 구문을 작성한 후,
Gradle을 새로고침하면
MySQL과 JPA를 사용할 준비는 끝난 것이다.

의존성 새로고침

application.properties에 DB접속정보 설정하기

의존성까지 추가했다면 MySQL에 연결하기 위한 설정을 하도록 한다.
MySQL 설정문자열은 `application.properties`에 작성한다.
구문은 다음과 같다.

spring.datasource.url=jdbc:mysql://localhost:3306/DB_스키마명?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username=DB_아이디
spring.datasource.password=DB_비밀번호
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

프로젝트를 실행하여
스프링부트 프로젝트가 실행되는 것을 확인한다.
정상적으로 실행된다면 `Tomcat started on port 8080` 메세지를 볼 수 있다.

Springboot3 프로젝트 실행

Entity 만들기

`ddl-auto`를 테스트하기 위해 EntityModel Class를 생성한다.
SpringBoot3에서 `Entity`는 DB 테이블과 1:1로 매핑되는 클래스를 의미한다.

package com.test.testspringboot3.ztest;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class EntityModel {

    @Id
    private Long id; /* 고유아이디 */

    private String title; /* 제목 */

    private String userId; /* 작성자 */

    private String createdAt; /* 생성일 */

    private String updatedAt; /* 수정일 */
}

spring.hibernate.ddl-auto 옵션 설정하고, 실행해 보기

ddl-auto 설정을 하기 위해
`application.properties`에
`spring.jpa.hibernate.ddl-auto`에 아래구문을 추가한다.
참고로 `#`은 주석을 의미한다.

spring.jpa.hibernate.ddl-auto=none
#spring.jpa.hibernate.ddl-auto=create
#spring.jpa.hibernate.ddl-auto=create-drop
#spring.jpa.hibernate.ddl-auto=update

테스트하기

이제부터 ddl-auto를 테스트할 수 있는 준비가 되었다.
SpringBoot3 프로젝트를 만들었고,
JPA 라이브러리를 추가했으며,
Entity 매핑을 위한 클래스를 만들고,
MySQL 연결까지 해 주었다.
`spring.jpa.hibernate.ddl-auto`옵션을 변경하며, 
SpringBoot3 프로젝트를 실행하면,
MySQL의 DB 테이블이 변경되는 것을 확인해 볼 수 있다.
하나씩 실행해 보도록 하자.

spring.jpa.hibernate.ddl-auto:none

`application.properties`에 작성한 `ddl-auto`를 `none`으로 설정하고
SpringBoot3 프로젝트를 실행시켜 본다.

# JPA
spring.jpa.hibernate.ddl-auto:none

이후 MySQL에 접속하여 DB 상태를 살패본다.

USE DB_스키마명;
SHOW TABLES;
ddl-auto:none
SHOW TABLES 결과

MySQL DB 스키마에 아무런 영향이 없다.
SpringBoot3가 시작될 때
JPA의 `spring.jpa.hibernate.ddl-auto:none`으로 설정을 준다면
DB스키마에 아무런 영향을 주지 않는다.

spring.jpa.hibernate.ddl-auto:create

`ddl-auto:create`는 SpringBoot3 프로젝트가 실행될 때
Entity 클래스를 기준으로 DB 스키마를 구성한다.
즉, DB 스키마의 테이블과 1:1 매핑구조를 만드는 Entity 클래스를 기준으로
DB 테이블이 만들어진다.
`applictaion.properties`의 ddl-auto를 create로 변경 후 
SpringBoot3 프로젝트를 실행해 보자.

# JPA
spring.jpa.hibernate.ddl-auto=create

이후 DB 스키마에 테이블이 생성되었는지 확인해 본다.

USE ztest;
SHOW TABLES;
ddl-auto:create
SHOW TABLES 결과

Entity 클래스를 기준으로 테이블이 생성되었다.

spring.jpa.hibernate.ddl-auto:create-drop

`ddl-auto:create-drop`은 SpringBoot3 프로젝트가 시작되면 
Entity 클래스 기준으로
MySQL 또는 연결된 DB 스키마에 Table생성하고, 
프로젝트가 종료되면 연동된 DB 스키마의 테이블들을 모두 삭제한다.
`
application.properties`의 ddl-auto`를 변경한 후 
SpringBoot3 프로젝트를 실행시켜 보자.

# JPA
spring.jpa.hibernate.ddl-auto=create-drop

DB 테이블의 상태를 살펴보자.

USE ztest;
SHOW TABLES;
ddl-auto:create-drop
SHOW TABLES 결과
SpringBoot3 프로젝트 
좌: 실행 시작 / 우: 실행 종료

현재 SpringBoot3에 연결된 DB는 MySQL이다.
`
프로젝트를 실행`하면 Entity 기준으로 `테이블이 생성`되고,
`
프로젝트를 종료`하면 `테이블이 삭제`되는 것을 볼 수 있다.

spring.jpa.hibernate.ddl-auto:update

`ddl-auto:update`는 SpringBoot3 프로젝트가 시작될 때 
Entity 클래스를 기준으로 프로젝트에 연결된 DB 스키마와 비교하여 
변경된 부분이 있다면 DB 스키마의 테이블들의 내용을 변경한다.
`application.properties`의 `ddl-auto`를 `update`로 변경한 후 
프로젝트를 실행해 본다.

# JPA
spring.jpa.hibernate.ddl-auto=update

DB 테이블의 상태를 보자.

ddl-auto: update
SHOW TABLES 결과

Entity를 기준으로 DB 스키마에 테이블이 생성되고, 컬럼이 추가된 것을 확인할 수 있다.
`ddl-auto: update`는 유연하다.
Entity 클래스를 기준으로 DB 스키마에 테이블이 없다면 생성하고,
Entity 클래스가 변경되면 DB 스키마의 테이블도 변경된다.
하지만, Entity 클래스명이 변경된다고 해서 DB 스키마의 테이블이 삭제되진 않는다.

spring.jpa.hibernate.ddl-auto:validate

`ddl-auto:validate`는 SpringBoot3 프로젝트가 시작될 때 
연결된 DB 스키마의 테이블을 Entity 클래스와 비교하고, 메제지만 표시한다.
JPA는 Entity 클래스를 기준으로 DB 스키마를 검사하고,
Entity 클래스와 DB 스키마의 테이블을 1:1 매핑한다는 점을 주목한다.
SpringBoot3 프로젝트가 시작하고 JPA 옵션이 `ddl-auto:validate` 라면 
JPA는 DB 스키마 테이블과 비교하고 다른 점이 있다면 `Exception` 메세지를 표시한다.
아래는 예시이다.

Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [test_entity_model]

메세지를 보면 Entity 클래스는 존재하지만
DB 스키마에 테이블이 없기 때문에 발생한 것이다.
하지만, DB 스키마에 영향은 없다.
이제 `ddl-auto:validate`를 변경한 후 
SpringBoot3 프로젝트를 실행시켜 본다.

# JPA
spring.jpa.hibernate.ddl-auto=validate

SpringBoot3 프로젝트가 실행된 후 메세지를 보자.

Entity 클래스와 DB 스키마 비교
좌: Entity , 우: DB

Entity 클래스는 3가지이고, DB 스키마의 테이블은 2개이다.
JPA 옵션이 `ddl-auto:validate`이고, SpringBoot3 프로젝트가 실행된다면
`Excepetion`이 발생될 것이다.

SchemaManagementException 발생
Entity 클래스와 DB 스키마의 테이블 불일치

위의 예시는 Entity 클래스와 DB 스키마의 테이블이 
불일치하여 발생한 예외를 보여준다.

정리

JPA는 Entity 클래스를 사용해 SpringBoot3와 연결된 DB 스키마를 검사하고, 설정하며,
`spring.jpa.hibernate.ddl-auto`옵션을 사용하면 된다.
해당 옵션은 `application.properties`에서 설정할 수 있다.
Entity 클래스와 DB 스키마 테이블들이 1:1 매핑을 사용하는 JPA 특성을 이용한다.
`Entity Class : DB Shcema Table = 1 : 1`
위의 내용들을 정리하면 다음과 같으며, 사용시 운영서버에 배포하는 경우 주의한다.

  • spring.jpa.hibernate.ddl-auto
    • none
      •  DB 스키마 자동 생성이나 변경을 전혀 하지 않음.
    • create
      • 기존 테이블을 모두 삭제 후 새로 생성.
      • 모든 데이터 삭제.
    • update
      • 엔티티와 DB 테이블 구조를 비교,  차이가 있는 부분을 수정
        • 테이블이 없다면 추가
        • 컬럼이 없다면 추가
      • 데이터 유지
    • create-drop
      • 프로젝트 시작시 DB 스키마의 테이블 생성 
        프로젝트 종료시 DB 스키마의 테이블 삭제
      • 모든 데이터 삭제.
    • validate
      • 엔티티와 DB 테이블 구조를 비교 차이가 있다면 예외 발생
      • 변경은 안 함.

댓글

이 블로그의 인기 게시물

AI 종류와 특징 / 모두 고유한 특징이 있다.

MySQL 테이블 생성 기본 템플릿 쿼리 만들기 CREATE TABLE

레이싱 마스터 PC 버전 에뮬레이터 설치 방법