DevLog ๐ถ
[Spring] Database Initialization : schema.sql๊ณผ data.sql ๋ณธ๋ฌธ
[Spring] Database Initialization : schema.sql๊ณผ data.sql
dolmeng2 2023. 4. 15. 16:03๐ฑ ๋ฌธ์ ์ํฉ
ํ์ด ํ๋ก๊ทธ๋๋ฐ์ ์งํํ๋ฉด์, ๋ถ๋ช ํ ์คํธ ์ฝ๋ ๊ฐ๊ฐ์ ์คํํ์ ๋๋ ์ ๋์๊ฐ๋๋ฐ ์ ์ฒด๋ฅผ ์คํํ๋๊น ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๋ฅผ ๋ง๋ฌ์๋ค.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceScriptDatabaseInitializer' defined in class path resource [org/springframework/boot/autoconfigure/sql/init/DataSourceInitializationConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #1 of URL [file:/Users/jw/Documents/wooteco/level2/jwp-racingcar/build/resources/main/data.sql]: CREATE TABLE RACE_RESULT ( `race_result_id` BIGINT ( 20 ) UNIQUE NOT NULL AUTO_INCREMENT, `trial_count` int NOT NULL, `winners` VARCHAR ( 50 ) NOT NULL, `created_at` DATETIME NOT NULL default current_timestamp, PRIMARY KEY ( `race_result_id` ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_general_ci; nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "RACE_RESULT" already exists; SQL statement:
๋์ถฉ ์ฝ์ด๋ณด๋ฉด, ์ด๋ฏธ ํ ์ด๋ธ์ด ์กด์ฌํ๋๋ฐ ์ ๋ ํ ์ด๋ธ์ ์์ฑํ๋๋ ๊ฒ์ด๋ค.
๋น์ data.sql ํ์ผ์ ์๋์ ๊ฐ์ด ์์ฑ๋์ด ์์๋ค.
CREATE TABLE RACE_RESULT
(
`race_result_id` BIGINT(20) UNIQUE NOT NULL AUTO_INCREMENT,
`trial_count` int NOT NULL,
`winners` VARCHAR(50) NOT NULL,
`created_at` DATETIME NOT NULL default current_timestamp,
PRIMARY KEY (`race_result_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE CAR
(
`car_id` BIGINT(20) UNIQUE NOT NULL AUTO_INCREMENT,
`name` VARCHAR(10) NOT NULL,
`position` int NOT NULL,
`race_result_id` BIGINT(20),
PRIMARY KEY (`car_id`),
UNIQUE uk_car_name_race_result_id (`name`,`race_result_id`),
FOREIGN KEY (`race_result_id`) REFERENCES RACE_RESULT (`race_result_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
์ฌ์ค ์ฒ์์๋ ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง ์ดํดํ ์๊ฐ ์์๋ค.
๊ฐ๋ณ ํ ์คํธ๋ ์ ๋์๊ฐ๊ธฐ ๋๋ฌธ์ ํ ์คํธ๋ง๋ค ํ ์ด๋ธ์ ์์ฑํ๊ณ , ํ ์คํธ๊ฐ ๋๋๋ฉด ํด๋น ํ ์ด๋ธ์ drop ์ํค๋ ํํ์ด๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ์๊ธฐ์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ค. + data.sql์ด ์ ํํ๊ฒ ๋ญ ํ๋ ์น๊ตฌ์ธ์ง๋ ์ดํดํ์ง ๋ชปํ๋ค ๐
๊ทธ๋์ ์ด๋ฅผ ๊ณ๊ธฐ๋ก ํ ๋ฒ ์ฐพ์๋ณด๊ณ ์ ํ๋ค.
โ๏ธ Spring Boot Data Initialization
์คํ๋ง ๋ถํธ์์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๊ธฐํ๋ฅผ ์ํ ๋ค์ํ ๋ฐฉ๋ฒ๋ค์ ์ ๊ณตํ๋ค.
์ด๋ฒ ๋ฏธ์ ์์๋ ๊ธฐ๋ณธ SQL ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฉํ์์ง๋ง, JPA๋ฅผ ํ์ฉํ ๋๋ ์ด๋ป๊ฒ ํ๋์ง ๊ถ๊ธํด์ ๊ฐ์ด ์์ฑํด๋ณด๊ณ ์ ํ๋ค.
๐ฑ JPA / Hibernate
JPA๋ DDL์ ์์ฑํ ๋ 2๊ฐ์ง ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ฐ, ์๋ฒ๊ฐ start ๋ ๋ ํด๋น ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ด๋ค ์์ผ๋ก ์ฐ์ฐ์ ์คํํ ์ง ์ง์ ํด์ค ์ ์๋ค. application.yml (application.properties)์ ์ ์ํ ์ ์์ผ๋ฉฐ, ๋ค์๊ณผ ๊ฐ์ ์ต์ ์ ์ฌ์ฉํ๋ค.
spring.jpa.generate-ddl (boolean)
spring.jpa.hibernate.ddl-auto (enum)
generate-ddl์ ๊ฒฝ์ฐ spring.jpa.hibernate.ddl-auto ์์ฑ์ ์ฌ์ฉํ ์ง ๋ง์ง ๊ฒฐ์ ํ๋ ์ต์ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ true, ํน์ false๋ก ์ง์ ํด์ค ์ ์๋ค. JPA๋ ๊ธฐ๋ณธ์ ์ผ๋ก @Entity + @Table, @Column ๊ฐ์ ์ด๋ ธํ ์ด์ ์ ํ์ฉํด์ ์ง์ ํ ์ด๋ธ create ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ์ง ์๋๋ผ๋ ์ฝ๋์์ ์ค์ ํ ์ ๋ณด๋๋ก ํ ์ด๋ธ์ ์์ฑํด์ค ์ ์๋ค.
๋ง์ฝ generate-ddl ๊ธฐ๋ฅ์ false๋ก ํ๊ฒ ๋๋ค๋ฉด ์๋ ์ด๊ธฐํ๋ฅผ ํ์ง ์๊ฒ ๋๋ฉฐ, true๋ฅผ ํ๊ฒ ๋๋ฉด ์ด๋ค ์์ผ๋ก ์ด๊ธฐํ๋ฅผ ํ ๊ฑด์ง ddl-auto๋ก ์ค์ ํ๋ค. (๊ทผ๋ฐ ddl-auto๋ฅผ ์ง์ ํ๊ฒ ๋๋ฉด generate-ddl์ true๋ก ๋ช ์์ ์ผ๋ก ์ง์ ํ์ง ์์๋ ์์์ ๋ง๋ค์ด์ฃผ๊ธฐ๋ ํ๋ค.)
+ ์๋ ์ด๊ธฐํ๋ผ๊ณ ํด์ ์ข์ ๊ฒ ๊ฐ์ง๋ง... ์ด์ ํ๊ฒฝ์์๋ ๋๋ถ๋ถ false๋ก ํ๋ ๊ฒ ์ข๋ค. (์์์น ๋ชปํ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ ์๋ ์์ - ์ด๋ฏธ ์ด์ ์ค์ธ ์๋น์ค์ db๋ฅผ ๊ฑด๋๋ ๊ฑด ์ฌ๊ฐํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ค.) ์ฌ๋งํ๋ฉด DB ํ ์ด๋ธ์ ๊ฑด๋๋ ์์ ์ ๊ทธ๋ฅ ์ง์ ํ ์ด๋ธ์ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฌ๋ ๊ฒ ์ข๋ค๊ณ ์๊ฐํ๋ค.
ddl-auto์ ๊ฒฝ์ฐ ์ด๋ค ์์ฑ์ ์ฌ์ฉํ ์ง ์ง์ ํด์ค ์ ์๋ค.
update: ๊ธฐ์กด์ ์คํค๋ง๋ฅผ ์ ์งํ๋ฉด์ ๋ณ๊ฒฝ๋ ๋ถ๋ถ์ ๋ํด์๋ง ์ ๋ฐ์ดํธ
validate: ์ํฐํฐ์ ํ ์ด๋ธ์ด ์ ์์ ์ผ๋ก ๋งคํ์ด ๋์๋์ง๋ง ํ์ธ
create: ๊ธฐ์กด์ ์กด์ฌํ๋ ์คํค๋ง๋ฅผ ์ญ์ ํ๊ณ ์๋ก ์์ฑ
create-drop: ์คํค๋ง๋ฅผ ์์ฑํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ ์ ์ญ์
none: ์๋ฌด๋ฐ ์ด๊ธฐํ ๋์์ ํ์ง ์์
๊ฐ์ธ์ ์ผ๋ก ๋ก์ปฌ ํ๊ฒฝ์์๋ update, ํ ์คํธ ํ๊ฒฝ์์๋ create-drop, ๊ฐ๋ฐ ํ๊ฒฝ์์๋ validate ์ ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ์ข์ ๊ฒ ๊ฐ๋ค. ํนํ create์ ๊ฒฝ์ฐ ์ฌ๋งํ๋ฉด ์ฌ์ฉํ์ง ์๋ ๊ฒ ์ข๋ค. ์ฐธ๊ณ ๋ก, ๊ธฐ๋ณธ๊ฐ์ ๊ฒฝ์ฐ create-drop์ด๊ธฐ ๋๋ฌธ์ ๋ง์ฝ ๋ณธ์ธ์ด ์์ฑํ ํ ์ด๋ธ์ด DB์ ๋ฐ์๋์ง ์์๋ค๋ฉด ํด๋น ์ต์ ์ด ์ง์ ๋์ด ์์ง ์์์ง ํ์ธํด๋ณด์.
create๋ create-drop์ผ๋ก ์ต์ ์ด ์ค์ ๋์ด ์์ ๊ฒฝ์ฐ, classpath์ ์กด์ฌํ๋ import.sql์ด๋ผ๋ ํ์ผ์ ์ฝ์ด์ ์คํํ๋ค. ์ฐธ๊ณ ๋ก ์ด๊ฑด Spring์ด๋ ๊ด๋ จ ์์ด Hibernate์ ๊ธฐ๋ฅ์ด๋ผ๊ณ ํ๋ค. (ํ ์คํธํ ๋ ์กฐ์ฌํ๋ผ๊ณ ์ ํ์๋ค...)
+ JDBC์์๋ JDBC url์ ๋ํ๋ Connection type์ ๋ฐ๋ผ์ ๊ฐ์งํ๋ค๊ณ ํ๋ค.
๐ฑ Basic SQL Scripts
์คํ๋ง ๋ถํธ๋ JDBC DataSource๋ R2DBC ConnectionFactory์ DDL script๋ฅผ ํตํด ์คํค๋ง๋ฅผ ์๋์ผ๋ก ์์ฑํ๊ณ , DML script๋ฅผ ๋ฐํ์ผ๋ก ์ด๋ฅผ ์ด๊ธฐํํ ์ ์๋ค. ์ด๋, ์ด๋ฌํ ์ด๊ธฐํ ๊ณผ์ ์ classpath์ ์กด์ฌํ๋ schema.sql๊ณผ data.sql์ ํตํด ๋ก๋๋๋ค! ๋ณดํต ํ ์ด๋ธ ์์ฑ ๊ฐ์ DDL์ ๊ฒฝ์ฐ schema.sql์, CRUD ๊ฐ์ ๊ธฐ๋ฅ์ data.sql์ ํ์ฉํ๋ ๊ฒ์ด ์ ์์ด๋ค.
๊ผญ ์ด๋ฆ์ด ์ด๋ ๊ฒ ์ง์ ๋ ํ์๋ ์์ผ๋ฉฐ, ์คํ๋ง๋ถํธ๋ schema-${platform}.sql์ด๋ data-${platform}.sql์ ์ฐพ์์ ์ฝ๋๋ค.
platform ๊ฐ์ ๊ฒฝ์ฐ ๋ง์ฐฌ๊ฐ์ง๋ก application.yml์ spring.sql.init.platform ์ต์ ์ ํตํด ์ง์ ์ด ๊ฐ๋ฅํ๋ฉฐ, ํน์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ๊ฒฝ์ ๋ํด์ ๋ค๋ฅธ ์คํฌ๋ฆฝํธ๋ฅผ ํ์ฉํ๊ณ ์ถ์ ๋ ์ ์ฉํ๋ค. (๋ฌธ๋ฒ์ด ๋ค๋ฅผ ๊ฒฝ์ฐ)
ex) spring.sql.init.platform=postgresql => schema-postgresql.sql์ ๋งค์นญ!
์๋ง ์ด๋ฐ ์์ผ๋ก ์ฌ์ฉํ์ง ์์๊น ์์๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ฌํ DB ์ด๊ธฐํ๋ in-memory db๋ฅผ ์ฌ์ฉํ ๋๋ง ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์, MySQL ๊ฐ์ ๋ค๋ฅธ ๋ฐ์ด๋ฒํ ์ด์ค์์๋ ์ ์ฉํ๊ณ ์ถ๋ค๋ฉด spring.sql.init.mode = always์ ๊ฐ์ด ์ค์ ํด์ผ ํ๋ค. ๋ฌผ๋ก , in-memory db์์๋ ์ฌ์ฉํ๊ณ ์ถ์ง ์๋ค๋ฉด spring.sql.init.mode=never๋ก ์ค์ ํ๋ฉด ๋๋ค.
๋ง์ฝ ์์ฑํ ์คํฌ๋ฆฝํธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค๋ฉด, ์๋ฒ๋ ์์๋์ง ์๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๊ฒ์ ๋ํด์๋ ์กฐ์ ํ๊ณ ์ถ๋ค๋ฉด spring.sql.init.continue-on-error๋ฅผ ์ฌ์ฉํ์ฌ ์ ์ดํ ์ ์๋ค. ๊ธฐ๋ณธ๊ฐ์ด false์ด๊ธฐ ๋๋ฌธ์, ์คํฌ๋ฆฝํธ์ ์๊ด์์ด ์๋ฒ๊ฐ ์คํ๋๊ธฐ๋ฅผ ์ํ๋ค๋ฉด ํด๋น ์ต์ ์ true๋ก ์ค์ ํ์.
๐ฑ Hibernate + Script
๋ง์ฝ hibernate ๊ธฐ๋ฐ ์ด๊ธฐํ์ script ๊ธฐ๋ฐ ์ด๊ธฐํ๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ ค๊ณ ํ๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
๋ฌผ๋ก , ๋ฒ ์คํธ๋ ๊ฐ์ด ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ์ข๋ค. ํนํ FlyWay ๊ฐ์ ๊ฒ๊ณผ ๊ฐ์ด ์ฌ์ฉํ๋ ๊ฑด ์์ ์ถ์ฒํ์ง ์๋๋ค. (ํฅํ ๋ฆด๋ฆฌ์ฆ์์ ์ ๊ฑฐ๋ ์์ ์ด๋ผ๊ณ ํ๋ค.)
๊ธฐ๋ณธ์ ์ผ๋ก ์คํฌ๋ฆฝํธ ๊ธฐ๋ฐ์ DataSource ์ด๊ธฐํ๋ JPA EntityManagerFactory ๋น์ด ์์ฑ๋๊ธฐ ์ ์ ์ํ๋๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์, ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ ๋ค์ ddl-auto ์ต์ ์ด ์ ์ฉ๋์ด ๋ง์ฝ ddl-auto๊ฐ create, create-drop์ด๋ผ๋ฉด ์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์์ฑํ๋ ํ ์ด๋ธ๋ค์ด drop ๋๊ณ ๋ค์ ์์ฑ๋ ์๋ ์๋ค.
ํ์ง๋ง, spring.jpa.defer-datasource-initialization=true๋ก ์ค์ ํ๊ฒ ๋๋ค๋ฉด, DataSource์ ๋ํ ์ด๊ธฐํ๋ฅผ EntityManagerFactory ๋น์ด ์์ฑ๋๊ณ ์ด๊ธฐํ๋ ๋๊น์ง ์ง์ฐ๋๋ค.
๊ถ๊ธํด์ ๋ค์๊ณผ ๊ฐ์ ์คํ์ ํด๋ณด์๋ค.
@Entity
@Table(name = "user")
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long id;
@Column(name = "user_name", unique = true, nullable = false)
private String name;
}
๊ฐ๋จํ User๋ผ๋ ์ํฐํฐ๋ฅผ ์์ฑํ์๋ค.
schema.sql
CREATE TABLE user
(
user_id BIGINT(20) NOT NULL AUTO_INCREMENT,
user_name varchar(255) UNIQUE NOT NULL,
PRIMARY KEY (user_id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
์ํฐํฐ์ ๋์ผํ ์คํค๋ง๋ฅผ ๊ฐ์ง๋๋ก ํ ์ด๋ธ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ์๋ค.
application.yml
spring:
datasource:
// db ์ค์
sql:
init:
mode: always
jpa:
hibernate:
ddl-auto: create
show-sql: true
defer-datasource-initialization: true
๊ณผ์ฐ ์ด๋ ๊ฒ ํ๋ฉด ์ ์์ ์ผ๋ก ์๋๋ ๊น?
๐ฌ ddl-auto: create + schema.sql + defer-datasource-initialization: true
์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
EntityManagerFactory์ด ๋จผ์ ์์ฑ๋๊ณ ์ด๊ธฐํ๊ฐ ๋์๊ธฐ ๋๋ฌธ์, @Entity๊ฐ ๋ถ์ ํด๋์ค์ ์ ๋ณด์ ๋ฐ๋ผ์ ํ ์ด๋ธ์ ์์ฑํ์ ๊ฒ์ด๋ค. ๊ทธ๋ฆฌ๊ณ , ๊ทธ ๋ค์ schema.sql์ ์๋ ๋ด์ฉ์ผ๋ก ํ ์ด๋ธ์ ์ด๊ธฐํํ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ ํ ์ด๋ธ์ด ์กด์ฌํ๋ค๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค.
๐ฌ ddl-auto: create + schema.sql + defer-datasource-initialization: false
๊ทธ๋ ๋ค๋ฉด, defer-datasource-initialization ์ต์ ์ ๋๋ฉด ์ด๋ป๊ฒ ๋์ํ ๊น?
์ต์ ์ ๋๋ฉด ์ ์์ ์ผ๋ก ์คํ์ ๋๋ค.
๋ค๋ง, schema.sql์ ํตํด ์์ฑ๋ ํ ์ด๋ธ์ ๋จผ์ drop ์ํค๊ณ ddl-auto๋ฅผ ํตํด ์๋กญ๊ฒ ํ ์ด๋ธ์ด ์์ฑ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
๊ทธ๋ผ, ์ด ์ํฉ์์ data.sql์ ์ถ๊ฐํด๋ณด์.
data.sql
INSERT INTO user(user_name) VALUES ('ํ
์คํธ์ด๋ฆ');
๐ฌ ddl-auto: create + schema.sql + data.sql + defer-datasource-initialization: false
๊ฒฐ๊ณผ๋ฅผ ๋ณด์. ์๋ฌด๊ฒ๋ ์ฝ์ ์ด ๋์ง ์์ ๊ฒ์ ๋ณผ ์ ์๋ค.
์์์ ๋งํ๋ ๊ฒ์ฒ๋ผ, ์ต์ ์ ๋ ์ํ์ด๊ธฐ ๋๋ฌธ์ datasource์ ๋ํด์ ๋จผ์ ์ด๊ธฐํ๋์ด ํ ์ด๋ธ ์์ฑ ํ insert๊น์ง ์งํํ์ง๋ง, ddl-auto๋ก ์ธํด์ ๋ค์ ๊ธฐ์กด์ ์๋ ํ ์ด๋ธ์ด drop ๋๊ณ ์ฌ์์ฑ๋๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง๊ฒ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด, ์ต์ ์ ๋ค์ true๋ก ์ค์ ํ๊ณ ์ค๋ฅ ๋ฐ์์ ๋ง๊ธฐ ์ํด schema.sql์ ์ ๊ฑฐํ์.
๐ฌ ddl-auto: create + data.sql + defer-datasource-initialization: true
์ฌ์ค ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ์์์ผ ๊ฒ ๊ฐ๋ค. (๋ก์ปฌ ํ๊ฒฝ์์)
๊ฐํธํ๊ฒ ํ ์ด๋ธ ์์ฑ ํ, ์ํ ๋ฐ์ดํฐ๋ฅผ insert ํด์ผ ํ๋ ์ํฉ์ด๋ผ๋ฉด ์์ ๊ฐ์ด ํ์ฉํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
๐ฑ ๊ทธ๋ ๋ค๋ฉด ์ฒ์์ ๋ฌธ์ ์ํฉ์ ์?
์ด๊ฑด ๊ฐ์ธ์ ์ธ ์๊ฐ์ด๋ผ ์กฐ๊ธ ๋ ์๊ฐ์ด ์ ๋ฆฌ๋๋ฉด ์์ ํ ์์ ์ด๋ค. (์์ง ํ ์คํธ ์ชฝ์ ์ ํํ ๋์ ์๋ฆฌ๋ฅผ ๋ชจ๋ฅด๊ฒ ๋ค...)
@SpringBootTest์ ๊ฒฝ์ฐ ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฆฌ๊ธฐ ๋๋ฌธ์ ๋์ผํ๊ฒ data.sql์ด ๋จผ์ ์ฝ์ด์์ ํ ์ด๋ธ์ ์์ฑํ์์ ๊ฒ์ด๋ค.
ํ์ง๋ง ํ ์คํธ๋ง๋ค ์๋ฒ๋ฅผ ๋์ฐ๋๋ผ๋ ๋ฐ๋ผ๋ณด๊ณ ์๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฒด๋ ๋์ผํ ๊ฒ์ด๊ณ (h2), ํ ์คํธ๋ ๋์์ ์คํ๋๋ค.
๊ทธ๋์ @SpringBootTest๊ฐ ๋ถ์ ์ด๋ค ํ
์คํธ์์ ์๋ฒ๋ฅผ ๋์ฐ๋ฉฐ data.sql์ ํตํด ํ
์ด๋ธ์ ์์ฑํ๋๋ฐ, ๋ ๋ค๋ฅธ @SpringBootTest๊ฐ ๋ถ์ ํ
์คํธ๊ฐ ์๋ฒ๋ฅผ ๋์ฐ๋ฉฐ data.sql์ ์ฝ์ด ํ
์ด๋ธ์ ์์ฑํ๋ ค๊ณ ๋๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๊ฒ ์๋๊น ์ถ๋ค.
(๋ณดํต์ ํ ์ด๋ธ ์์ฑ ์์ฒด๋ฅผ ํ ์คํธํ๊ธฐ ๋ณด๋จ, ํ ์คํธ ๋ ๋ฆฝ์ฑ์ ๋กค๋ฐฑ์ ํตํด ์์ฑ๋ ํ ์ด๋ธ์ ์ปฌ๋ผ์ด ๋จ์ง ์๋๋ก ํ๋ ๊ฒ ์ผ๋ฐ์ ์ด๋๊น...)
๊ฐ ๋ง๋์ด๋ ๋ํ๋ฅผ ๋๋๊ณ ์๊ฐ์ด ์ ๋ฆฌ๋์๋ค.
Spring Boot์์ ํ ์คํธ ํ๊ฒฝ์ ๊ตฌ์ถํ ๋ bean์ด ์ฌ๋ฌ ๊ฐ๊ฐ ๋ฑ๋ก๋๋ค๋ฉด ApplicationContext๊ฐ ํ์ํ๊ณ , ApplicationContext๋ ๊ณง ํ ์คํธ์์ ์ฌ์ฉ๋๋ bean์ผ๋ก ๊ตฌ์ฑ๋๋ค. ์ด๋, ํ ์คํธ๋ง๋ค ์๋ก์ด ApplicationContext๋ฅผ ์์ฑํ๋ค๋ฉด ๋น์ฐํ ์ฑ๋ฅ์ ์ผ๋ก ์ข์ง ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ๊ฐ์ bean์ ์ฌ์ฉํ๊ฑฐ๋ ์ค์ผ๋์ง ์์์ ๊ฒฝ์ฐ ์บ์ฑ์ ํ๊ฒ ๋๋ค. (์บ์ฑ์ ๋ํด์๋ ํ ๋ฒ ์ฐพ์๋ด์ผ๊ฒ ๋ค.)
๊ทธ๋์ @SpringBootTest ์์ฒด์ ๋ฌธ์ ๋ผ๊ธฐ๋ณด๋จ, ํ ์คํธ์์ ํ์ํ ๋น์ด ๋ฌ๋ผ์ก๋ค๋ ์ง, mock ๋ฑ์ ํตํ ์ค์ผ์ผ๋ก ์ธํด ๊ธฐ์กด์ db๋ฅผ ์ฌ์ฉํ๊ณ ์์์๋ ์๋ก์ด ApplicationContext๋ฅผ ๊ตฌ์ฑํ๋ ๊ฒฝ์ฐ data.sql์ ํ ๋ฒ ๋ ์ฝ์ผ๋ฉด์ ๋์ผํ db์ ํ ๋ฒ ๋ ํ ์ด๋ธ์ create ํ๋ฉด์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ผ๋ก ์ถ์ธก๋๋ค!
CREATE TABLE IF NOT EXISTS RACE_RESULT
(
`race_result_id` BIGINT(20) UNIQUE NOT NULL AUTO_INCREMENT,
`trial_count` int NOT NULL,
`winners` VARCHAR(50) NOT NULL,
`created_at` DATETIME NOT NULL default current_timestamp,
PRIMARY KEY (`race_result_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
CREATE TABLE IF NOT EXISTS CAR
(
`car_id` BIGINT(20) UNIQUE NOT NULL AUTO_INCREMENT,
`name` VARCHAR(10) NOT NULL,
`position` int NOT NULL,
`race_result_id` BIGINT(20),
PRIMARY KEY (`car_id`),
UNIQUE uk_car_name_race_result_id (`name`,`race_result_id`),
FOREIGN KEY (`race_result_id`) REFERENCES RACE_RESULT (`race_result_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci;
๊ทธ๋์ ๊ฒฐ๊ณผ์ ์ผ๋ก๋ IF NOT EXISTS๋ฅผ ๋ถ์ฌ์ฃผ์ด, ์ด๋ฏธ ํ ์ด๋ธ์ด ์กด์ฌํ ๊ฒฝ์ฐ ์์ฑํ์ง ์๋๋ก ๋ง๋ค์ด์ฃผ์๋ค.
์ญ์ Spring์ ๋ํด ์์ง ๋ชจ๋ฅด๋ ๊ฒ ๋๋ฌด ๋ง๋ค...
์ด์ฌํ ๊ณต๋ถํด์ผ๊ฒ ๋ค!