잘못된 내용이 있습니다. 참고용으로만 사용해주시기 바랍니다. 글을 내리려다 꾸준히 오시는 분들이 계셔서 그대로 유지하고 있습니다.
감사합니다.
환경 : 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이 설치된다.
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
# 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이다
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
김영한님의 스프링 입문 강의 섹션 6 : H2 데이터베이스
Gardle Doc : What are dependency configurations
Stack overflow : Gradle dependency configuration : implementation vs api vs runtimeonly
'☕️ JAVA > 🍃 Spring' 카테고리의 다른 글
스프링 부트 살펴보기 / 의존성 관리 간소화, 배포 간소화, 자동 설정 (0) | 2023.06.04 |
---|---|
Maven Standard Directory Layout과 plain jar, executable jar (0) | 2022.12.28 |
Spring VS Spring Boot 몇 가지 차이점 (2) | 2022.09.23 |
./gradlew bootRun vs java -jar로 실행할 때의 차이점 (리소스 경로) (0) | 2022.03.19 |
댓글