0. 도입
최근 간단한 사이드 프로젝트를 진행하던 중 데이터 베이스 선택 문제를 겪었습니다.
간단한 서비스인데 DB 설정 때문에 프로젝트 시간이 오래 걸려 의문이 생겼습니다.
간단한 프로젝트나 테스트를 할 때, DB 설정 시간을 최소한으로 줄일 수는 없을까?
이처럼 사용자가 적은 서비스 이거나 간단한 단위 테스트만 필요한데 DB때문에 시간이 길어지는 불편함이 생길 수 있습니다. 흔히 겪는 불편한 점은 다음과 같습니다.
- 여러 개발자들이 사용하는 경우 의도치 않게 DB가 변경될 수 있다.
- 운영 DB와 마찬가지로 보안 문제로 외부 접속이 어렵다.
- 테스트를 실행할 때마다 DB를 켜고 설정해야 한다.
이렇게 테스트를 위한 작업들이 많아지면 결국 테스트 시간이 지연되고 개발 전체 시간이 길어집니다. 또한 사용자가 많지 않아서 DB가 중요하지 않은 간단한 서비스나 토이프로젝트에서도 DB에 신경쓰느라 배보다 배꼽이 더 커지는 상황이 발생합니다.
저도 최근에 이용자가 아주 적은 간단한 서비스를 만들면서 비슷한 문제를 만났는데, 이때 찾은 해결책이 H2 DB입니다. 이렇게 H2를 처음 공부하고 사용하다 보니 생각보다 이점이 많고 앞으로도 자주 쓸 것 같아서 이번 기회에 공부하여 정리하고 넘어가려고 합니다.
이번 포스팅에서는 앞에서 겪은 문제 상황을 바탕으로 간단한 게시판 단위 테스트를 가정하여 H2 데이터 베이스의 특징과 사용 방법에 대해서 정리해 보도록 하겠습니다.
1. H2 DB 소개
H2 DB란?
Java로 작성된 관계형 데이터베이스 관리 시스템
위에서 관계형 데이터베이스(RDB)란 서로 관련된 데이터 지점에 대한 접근을 저장 및 제공하는 데이터베이스 유형입니다.
간단히 말해 관계형 데이터베이스 관리 시스템은 여러 테이블의 관계를 포함하여 관리해주는 시스템입니다.
H2는 Java로 작성되었기 때문에 편리한 특징들이 있습니다.
- 스프링 부트에 연동해서 따로 설치하지 않아도 웹 콘솔로 접근할 수 있다.
- 다른 SQL 방언들을 적용할 수 있다.
- 특히, In-Memory모드를 사용하면 Ram을 사용하여 매우 빠르게 CURD 연산을 테스트할 수 있다.
H2는 이런 편의성을 가지고 있어 로컬 개발 환경에서 빠르게 단위 테스트를 진행할 때 자주 사용합니다.
물론, 대규모 프로젝트에서는 안정성과 성능이 부족하여 MySQL, Oracle과 같은 표준적인 RDBMS를 사용하는 것이 좋습니다.
H2의 세 가지 모드
H2는 세 가지 모드를 지원합니다.
In-Memory Mode
- 스프링부트 실행시 램에서 데이터를 생성하고 종료시 데이터가 휘발된다.
- 매우 빠르게 DB를 생성하여 간단한 단위 테스트에 유용하다.
Embeded Mode
- In-Memory Mode와 비슷하지만 로컬 환경에 DB를 생성한다.
- 프로그램을 종료해도 로컬 DB에 남아있다.
Server Mode
- 다른 곳에 H2와 JDK를 설치하여 환경을 구축하고 접속할 수 있다.
- 외부에서 TCP/IP를 통해 접속해야 한다.
In-Memory Mode와 Embeded Mode는 스프링부트에 연동하면 자체적으로 실행해서 매우 빠르게 DB를 구축할 수 있습니다.
보통 외부 서버에 DB를 구축할 때에는 Sever Mode를 사용합니다.
이번 포스팅에서는 스프링부트 자체에서 실행하는 In-Memory Mode와 Embeded Mode를 중심으로 다루어 보도록 하겠습니다.
2. H2 사용법
DB 의존성 추가
먼저 build.gradle에 의존성을 추가해 주어야 합니다.
build.gradle
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-jpa'
implementation 'com.h2database:h2'
...
}
spring-boot-starter-jdbc 또는 spring-boot-starter-jpa를 사용하면 DataSource 구현체로 tomacat-jdbc를 사용합니다. 여기서는 jpa를 사용하도록 하겠습니다.
DB 정보 설정하기
다음으로 설정을 추가해 주어야 합니다. H2의 모드에 따라 application.properties의 설정값이 달라집니다. 먼저 In-Memory Mode부터 보겠습니다.
In-Memory Mode
application.properites
#H2
spring.h2.console.enabled=true
spring.datasource.generate-unique-name=false
spring.datasource.url=jdbc:h2:mem:testdb
#JPA
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.jpa.defer-datasource-initialization=true
첫 번째 설정은 웹 콘솔로 접근할 수 있도록 하는 설정입니다.
두 번째 와 세 번째 설정으로 DB의 URL을 설정할 수 있습니다. 원래는 매 실행마다 랜덤으로 DB의 주소가 생성됩니다. 하지만 이 설정을 통해 랜덤 주소 대신 "jdbc:h2:mem:testdb"로 매칭하여 쉽게 접근할 수 있습니다.
네 번째 설정은 SQL의 방언 설정입니다. 테스트 실행마다 SQL 쿼리문을 실행시킬 수 있는데 방언 설정을 통해 H2에서 MySQL을 인식할 수 있습니다.
다섯 번째 설정은 JPA가 초기화되기 전에 Datasource가 초기화되어 SQL파일이 실행되도록 합니다. 간단한 데이터 출력 테스트를 위해 설정했습니다.
일반적으로 H2를 사용할 때에는 세 번째 까지만 설정하면 됩니다. 저는 데이터를 직접 넣고 확인하기 위해 네 번째와 다섯 번째 설정을 추가하였습니다.
그리고 간단한 출력 확인을 위해 application.properties와 같은 경로에 schema.sql과 data.sql을 만들어 주었습니다.
schema.sql
CREATE TABLE article (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
content VARCHAR(255)
);
data.sql
INSERT INTO article(title, content) VALUES('삼성전자', '2주 매수');
INSERT INTO article(title, content) VALUES('SK하이닉스', '2주 매수');
INSERT INTO article(title, content) VALUES('한미반도체', '3주 매수');
INSERT INTO article(title, content) VALUES('HD현대일렉트릭', '2주 매수');
이제 스프링 부트를 실행하고 주소창에 "localhost:8080/h2-console"을 입력하면 웹 콘솔을 통해 DB에 접속됩니다. JDBC URL 입력란에 위에서 설정한 jdbc:h2:mem:testdb" 를 입력하고 Connect를 눌러주면 DB에 접속됩니다.
접속하면 아래와 같이 DB 관리창에 ARTICLE 테이블이 이미 생성되어 있습니다. 쿼리 창에 "SELECT * FROM ARTICLE"을 입력하고 Run을 눌러줍니다. 이 명령어는 article 테이블로부터 모든 정보를 조회하는 명령어 입니다.
JPA가 초기화되기 전에 SQL 쿼리가 먼저 실행되었고 데이터가 DB에 잘 저장되었습니다. 이렇게 In-Memory Mode를 사용하면 즉석에서 바로 단뒤 테스트를 위한 환경을 구축할 수 있습니다.
이제 Embeded Mode를 살펴보겠습니다.
Embeded Mode
application.properites
# H2 DB
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.web-allow-others=true
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:~/testdb
spring.datasource.username=sa
#JPA
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
첫 번째와 두 번째 설정은 In-Memory Mode와 비슷하니 세 번째 설정을 살펴보겠습니다.
세 번째 설정으로 외부 접속을 허용할 수 있습니다. 만약 배포 환경이거나 외부에서 접속하여 테스트를 할 경우 유용합니다.
마지막 설정은 DB 생성 전략입니다. ddl-auto = update를 통해 만약 DB 테이블이 없으면 생성하고, 이미 테이블이 존재하면 바뀐 부분만 업데이트하게 됩니다. 테스트 환경에서 update 속성을 주로 사용합니다.
DB생성 전략은 JPA에서 중요한 내용이므로 기회가 되면 정리할 예정입니다.
보통 이름과 password도 설정할 수 있지만 생략하기도 합니다.
이제 스프링부트를 실행하면 In-Memory Mode와 달리 C:\Users\private 경로에 testdb.mb파일이 자동으로 생성됩니다.
In-Memory Mode처럼 콘솔에서 실행하면 똑같이 DB에 접속할 수 있습니다.
yml으로 설정
참고로 위와 같이 application.properties로도 설정할 수도 있고 application.yml파일로도 설정할 수 있습니다. 최근에는 편리하고 가독성이 좋은 yml로 정보를 기입하는 추세입니다.
전체 설정을 위한 yml파일은 다음과 같습니다.
application.yml
spring:
# H2 Database 설정
datasource:
driver-class-name: org.h2.Driver
#url: 'jdbc:h2:mem:test' # H2 DB 연결 주소 (In-Memory Mode)
url: 'jdbc:h2:~/test' # H2 DB 연결 주소 (Embedded Mode)
username: username # H2 DB 접속 ID (사용자 지정)
password: password # H2 DB 접속 PW (사용자 지정)
# H2 Console 설정
h2:
console: # H2 DB를 웹에서 관리할 수 있는 기능
enabled: true # H2 Console 사용 여부
path: /h2-console # H2 Console 접속 주소
# JPA 설정
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: update # DB 초기화 전략 (none, create, create-drop, update, validate)
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
format_sql: true # 쿼리 로그 포맷 (정렬)
show_sql: true # 쿼리 로그 출력
3. 정리
H2 DB는 주로 간단한 테스트를 위한 교육용으로 많이 사용해서 DB를 처음 입문하는 용으로 배울게 많은 도구입니다. H2 DB는 인메모리 모드로 사용할 경우 아주 빠르게 간단한 단위 테스트를 진행할 수 있습니다.
하지만 매 실행마다 더미 데이터를 초기화해야 하는 단점이 있습니다. 따라서 적합한 상황에서 H2 DB를 사용하여 개발 시간을 단축할 수 있습니다. 무엇보다 중요한 것은 상황에 맞게 사용하는 것입니다. 이 글을 바탕으로 직접 서비스를 구축하며 다른 기능들도 익히면 많은 도움이 될 것입니다.
다음에는 H2 DB의 Server Mode로 실행하는 방법에 대해서는 다음 포스팅에서 다루어 볼까 합니다. 궁금한 점은 댓글로 남겨주세요! 도움이 되었다면 좋아요 부탁드려요
참고 자료
'Data Base' 카테고리의 다른 글
[데이터 베이스] Window11 MySQL 설치 및 실행 방법 (0) | 2024.07.27 |
---|
경이로운 BE 개발자가 되기 위한 프로그래밍 공부 기록장
도움이 되었다면 "❤️" 또는 "👍🏻" 해주세요! 문의는 아래 이메일로 보내주세요.