본문 바로가기
☕️ JAVA/🍃 Spring

Spring boot에서 H2 DB 3가지 모드 사용하기(embedded, In-Memory, Server)

by kukim 2022. 3. 16.

잘못된 내용이 있습니다. 참고용으로만 사용해주시기 바랍니다. 글을 내리려다 꾸준히 오시는 분들이 계셔서 그대로 유지하고 있습니다.
감사합니다.

 

환경 : Java 11 + Spring Boot 2.6.2 + Gradle

데이터베이스 : H2 DB


H2 DB의 3가지 모드

H2DB자바 기반 오픈소스 RDBMS(관계형 데이터 베이스 관리 시스템)이다.

H2DB Cheat Sheet를 살펴보면 세 가지 용도를 찾을 수 있다.

1. Embedded Mode

2. In-Memory Mode

3. Server Mode

 

Server Mode

Server Mode는 공식 사이트에서 H2를 Plafform-Independent 버전을 다운로드하고 h2/bin/h2.sh를 터미널로 실행하면 h2가 TCP 통신을 할 수 있는 서버 버전으로 실행된다고 볼 수 있다. 따라서 외부에서 h2 서버가 실행되어야 스프링에서 application.properties에 h2서버 주소를 입력해 접속할 수 있다. 김영한님의 스프링 입문 강의 섹션 6 : H2 데이터베이스(무료강의)에서 사용하는 방법이 Server Mode를 사용하는 것이다.

 

Embedded Mode, In-Memory Mode

Server Mode는 외부에서 터미널로 h2.sh 실행 또는 빌드되어있는 h2.jar를 java -jar로 실행시켜야한다. 이는 스프링 부트안에서 한 번에 띄우는 것이 아니기 때문에 스프링을 띄우고, 외부에서 h2 DB를 다른 DB를 띄우는 것과 유사하게 불편하다. 하지만 h2의 Embedded, In-Memory Mode는 공식 사이트에서 H2를 다운로드하지 않아도 build.gradle에 H2 의존성을 추가하여 간편하게 할 수 있다. H2 DB를 직접 터미널로 실행시켜 스프링과 연결시키는 것이 아니라 스프링이 빌드, 실행될 때 의존성으로 받아온 H2의. jar로 H2를 자체적으로 띄워 접속할 수 있다. 따로 DB를 띄우지 않아도 손쉽게 데이터베이스를 사용할 수 있기에 테스트 용도로 자주 사용된다.

 

Embedded Mode :  스프링 부트 실행할 때 함께 H2를 띄운다. H2 DB 데이터를 로컬에 직접 저장하고 사용한다.

In-Memory Mode : 스프링 부트 실행할 때 함께 H2를 띄운다. H2 DB 데이터를 로컬에 저장하지 않고 메모리에만 가지고있다.

Embedded, In-Memory Mode 사용 방법

두 모드는 저장소 위치 설정만 다르고 사용 방법은 동일하다.

사용 방법은 아래와 같다.

1. build.gradle에 h2 의존성 추가

2. application.properties에 h2 관련 환경 설정

- h2 DB 초기화할 .sql 설정

1. build.gradle에 h2 의존성 추가하기

dependencies {
   // 생략
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
   // 생략
   // 아래 두개 추가
   implementation 'org.springframework.boot:spring-boot-starter-jdbc' // Jdbc, Driver
   implementation 'com.h2database:h2' // h2 : implementation 
   // runtimeOnly 'com.h2database:h2' // h2 : runtimeOnly
}

spring-boot-starter-jdbc와 com.h2 database:h2를 추가해주면 된다. 하지만 gradle 의존성 추가 옵션을 implementation 또는 runtimeOnly으로 선택할 수 있다. (+a, gradle에 의존성 추가하는 옵션은 다양하다. implementation, testImplementation, testCompile, api, runtimeOnly... 이는 classpath와 관계가 있다. 간단히 설명하면 컴파일할 때 사용되는 class, 런타임에 필요한 class를 나타내는 것이다. (Gardle Doc : What are dependency configurations))

이 옵션의 차이는 DB의 테이블과 데이터를 초기화할 때 사용되는. sql 파일을 자동으로 읽을지 직접 경로를 입력할지 차이다.

 

Implementation 'com.h2database:h2'

implementation는 컴파일 시간에 종속된 모듈을 노출시키지 않기 때문에 데이터 베이스를 초기화할. sql 파일을 자동으로 읽을 수 없어 실행할. sql 파일을 application.properties에 직접 추가해줘야 한다.

 

runtimeOnly 'com.h2database:h2'

runtimeonly는 런타임 중에 종속성을 추가한다. 따라서 application.properties에 초기화 파일 경로를 입력하지 않아도 된다.

 

+a) com.h2database:h2 로 받는다면 1.4.200이 설치된다.

https://docs.spring.io/spring-boot/docs/current/reference/html/dependency-versions.html#appendix.dependency-versions

2. application.properties 설정

설정

# application.properties 파일

# h2 database web으로 확인
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

# spring - h2 연결
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:~/spring-qna-db # embedded Mode : db 데이터 저장 위치 :  ~/spring-qna-db
#spring.datasource.url=jdbc:h2:mem:test # In-Memory mode 
spring.datasource.username=sa
spring.datasource.password=

spring.sql.init.mode=always
#spring.sql.init.schema-locations=classpath:schema.sql
#spring.sql.init.data-locations=classpath:data.sql

H2 콘솔 , web으로 확인하기

h2 database는 실행하면 웹 환경에서 DB를 손쉽게 사용할 수 있다. 만약 스프링 서버가 8080 포트로 띄워져 있다 가정한다면 localhost:8080/h2-console를 통해 H2 DB를 접속할 수 있다.

# h2 database web으로 확인
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

localhost:8080/h2-console


# spring - h2 연결
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:~/spring-qna-db # embedded Mode : db 데이터 저장 위치 :  ~/spring-qna-db
#spring.datasource.url=jdbc:h2:mem:test # In-Memory mode
spring.datasource.username=sa
spring.datasource.password=

spring.datasource.driverClassName= org.h2.Driver

spring과 H2 접속할 수 있는 드라이버 설정

 

spring.datasource.url=?

H2 데이터베이스의 데이터를 저장할 위치를 정할 수 있다. 이 위치에 따라 Embedded Mode, In-Memory Mode가 정해진다.

 

spring.datasource.url=jdbc:h2:~/spring-qna-db 

~/spring-qna-db에 파일을 생성하고 이를 DB 데이터 파일로 사용한다는 뜻이다. 이는 Embedded Mode이다

Embedded Mode

spring.datasource.url=jdbc:h2:mem:test

In-Memory Mode로 사용할 때 위 옵션을 주면 된다. 로컬에 데이터를 저장하지 않고 메모리 상에서만 데이터가 저장된다.

 

spring.datasource.username=sa
spring.datasource.password=

h2-console에서 접속할 username과 password이다.


H2 초기화할 .sql 실행 

H2가 실행될 때마다 테스트할 테이블(schema.sql)과 더미 데이터(data.sql)를 생성한다고 하자.

 

schema.sql 예

DROP TABLE IF EXISTS USER;
CREATE TABLE USER
(
    user_id  VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    `name`   VARCHAR(255),
    email    VARCHAR(255),
    PRIMARY KEY (user_id)
);

data.sql 예

INSERT INTO USER VALUES ('bob','1234','bob1','bob@gmail.com');
INSERT INTO USER VALUES ('jona','1234','jona1','jona@gmail.com');
INSERT INTO USER VALUES ('kim','1234','kim1','kim@gmail.com');
INSERT INTO USER VALUES ('lee','1234','lee1','lee@gmail.com');

 

Implementation 'com.h2database:h2'

의존성 추가에 Implementation으로 했다면 초기화할 schema.sql, data.sql 경로를 입력해야 한다. 

따라서 application.properties에 해당 .sql를 추가한다. 여기서 classpath는 src/main/resoucres/schema.sql , data.sql 이다.

spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:schema.sql
spring.sql.init.data-locations=classpath:data.sql

 

 

runtimeOnly 'com.h2database:h2' 

spring.sql.init.mode=always

만약 H2 의존성을 runtimeOnly로 설정해주었다면 resources 폴더 바로 밑에 "schema.sql", "data.sql" 파일을 자동으로 읽어 H2 데이터베이스를 초기화한다.

 

+a) localhost가 아닌 외부 배포 후 h2에 접속하는 방법 ('webAllowOthers')

+a) 22.09.06 추가

local에서 h2를 사용하여 h2-console에 접속이 아닌 배포 환경에서 접속할 경우가 있다.

이때 접속하면 "Sorry, remote connections ('webAllowOthers') are disabled on this server." 문구가 나오며 접속할 수 없다.

이를 위해서 application.* 파일에 web-allow-others: true를  추가해주면 된다.

  h2:
    console:
      enabled: true
      settings:
        web-allow-others: true  # 추가

출처: https://moonsiri.tistory.com/33 [Just try it!:티스토리]


Reference

H2DB 공식 사이트

H2DB cheatSheet

김영한님의 스프링 입문 강의 섹션 6 : H2 데이터베이스

Gardle Doc : What are dependency configurations

Stack overflow : Gradle dependency configuration : implementation vs api vs runtimeonly

댓글