Initialize a Database Using JPA
JPA에는 DDL 생성 속성이 존재한다. 엔티티에 매핑되는 테이블이 데이터베이스에 없는 경우 애플리케이션 초기화 단계에서 적절하게 테이블을 생성해 준다.
물론 종료 시 삭제, 업데이트, 아무런 일도 하지 않도록 설정할 수 있다.
spring.jpa.generate-ddl이라는 external properties을 통해 DDL 기능을 끄고 킬 수 있다.
spring.jpa.hibernate.ddl-auto (enum)은 다양한 행동을 지정한다.
Spring boot는 내장 데이터베이스가 감지된 경우만 created-drop 옵션으로 동작합니다. 그 외에는 none으로 기본값을 가집니다.
이러한 schema creation을 활성화시키기 위해선 org.hibernate.SQL의 debug mode를 활성화하면 된다.
💡 JPA 구현체로 Hibernate를 사용하는 경우, root의 classpath에 있는 import.sql이라는 파일이 실행됩니다. 이는 spring과 관련 없는 기능입니다.
Initialize a Database Using Basic SQL Scripts
Spring Boot는 JDBC DataSoruce 또는 R2 DBC ConnectionFactory의 스키마를 자동으로 생성하고 이를 초기화할 수 있습니다. 이는 root classpath에 위치한 schema.sql, data.sql 로드하기 때문입니다.
기본적으로 데이터베이스 초기화는 임베디드 인메모리 데이터베이스를 사용할 때만 수행됩니다. 만약 유형에 관계없이 SQL 베이스를 항상 초기화하려면 다음 속성을 aways로 설정하면 됩니다.
spring.sql.init.mode=aways
or
spring.sql.init.mode=never
💡 Spring Boot는 init 스크립트에서 오류 발생 시 애플리케이션이 동작되지 않습니다. 해당 속성을 변경하려면 spring.sql.init.continue-on-error 속성을 참고하세요
그럼 JPA generate-ddl 속성과 Spring sql init 중 어떠한 속성이 먼저 실행될까?
Script-based 데이터베이스 초기화는 기본적으로 JPA EntityManagerFactory Bean이 생성되기 이전에 수행됩니다.
그렇기에 schema.sql로 JPA 엔티티에 대한 스키마를 사전에 만들고 data.sql로 엔티티에 대한 데이터를 채울 수 있습니다.
기본적으로 데이터 초기화 스크립트의 혼용은 추천되지 않습니다.
스크립트 기반한 DataSoruce 초기화가 Hibernate에서 수행되는 스키마 생성을 기반으로 수행하도록 spring.jpa.defer-
datasoruce-initialization을 true로 설정하면 됩니다.
이렇게 하면 DataSoruce 초기화가 EntityManagerFactory 빈이 생성되고 초기화될 때까지 지연됩니다.
그런 다음 schema.sql을 사용하여 스키마를 생성하고 data.sql을 통해 스키마를 채울 수 있습니다.
💡 기본 schema.sql 및 data.sql 스크립트를 Flyway 또는 Liquibase와 함께 사용하는 것은 권장되지 않으며 향후 릴리스에서 지원이 제거될 예정입니다.
우선적인 내 목적은 schema.sql, data.sql을 사용하여 기본 데이터를 애플리케이션 초기화 시점에 생성하는 것이다.
메모리 데이터베이스라 애플리케이션 종료 시 데이터도 날아가니 빠르게 테스트할 수 있다.
1.schema.sql
DROP TABLE IF EXISTS worker;
create table worker (
id bigint not null,
email varchar(255),
image_url varchar(255),
name varchar(255),
video_url varchar(255),
created_at timestamp,
updated_at timestamp,
primary key (id)
);
2.data.sql
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (1, 'John', 'john@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (2, 'Alice', 'alice@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (3, 'Bob', 'bob@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (4, 'Eva', 'eva@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (5, 'Michael', 'michael@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (6, 'Sarah', 'sarah@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (7, 'David', 'david@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (8, 'Olivia', 'olivia@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (9, 'Daniel', 'daniel@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (10, 'James', 'james@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO worker (id, name, email, image_url, video_url, created_at, updated_at)
VALUES (11, 'Emily', 'emily@email.com', '/static/img/logo.jpg', '/static/video/1.mp4',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
3.application.yml
spring:
profiles:
include: oauth2, logging
datasource:
url: jdbc:h2:mem:testdb
username: sa
password:
jpa:
open-in-view: false
properties:
hibernate:
format_sql: true
jdbc:
batch_size: 100
show-sql: true
hibernate:
ddl-auto: none
generate-ddl: false
h2:
console:
enabled: true
path: /h2-console
logging:
level:
org.hibernate.SQL: DEBUG
org.hibernate.type.descriptor.sql.BasicBinder: TRACE
org.springframework.web: DEBUG
'Spring|Spring-boot > Spring-Data-JPA' 카테고리의 다른 글
Projections (1) | 2022.12.03 |
---|---|
스프링 데이터 JPA 구현체를 알아보자. (0) | 2022.12.03 |
도메인 컨버터 & 페이징과 정렬 (0) | 2022.12.03 |
Auditing (0) | 2022.11.30 |
Custom Repository (0) | 2022.11.30 |
댓글