Spring Boot H2 콘솔 — 인메모리 DB로 빠른 개발 환경 구성
Spring Boot 개발 환경에서 H2 인메모리 데이터베이스와 웹 콘솔을 설정하는 방법을 다룹니다. 의존성 추가부터 MySQL 호환 모드, Spring Security 통합, 테스트 격리 전략까지 실용적인 구성을 설명합니다.
지난 글에서 Flyway와 Liquibase로 DB 스키마를 버전 관리하는 방법을 살펴봤습니다. 개발 초기 단계나 단위 테스트에서는 매번 외부 DB를 띄우는 것이 번거롭습니다. 이때 H2 인메모리 데이터베이스가 강력한 대안이 됩니다. 외부 설치 없이 JVM 프로세스 내에서 동작하고, 기동 즉시 사용 가능하며, 브라우저에서 SQL을 직접 실행할 수 있는 웹 콘솔까지 제공합니다.
H2란
H2는 자바로 작성된 경량 관계형 데이터베이스입니다. 인메모리 모드(jdbc:h2:mem:)와 파일 모드(jdbc:h2:file:) 두 가지로 실행됩니다. 인메모리 모드는 앱이 종료되면 데이터가 사라지는 대신 디스크 I/O 없이 빠르고 설치가 필요 없습니다.
스프링 부트는 spring-boot-starter-data-jpa와 함께 h2가 클래스패스에 있으면 자동으로 인메모리 DB를 구성합니다. 추가 설정 없이 바로 사용할 수 있습니다.
의존성 추가
<!-- pom.xml -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
// build.gradle
runtimeOnly 'com.h2database:h2'
scope=runtime(Maven) 또는 runtimeOnly(Gradle)로 지정합니다. 컴파일 클래스패스에는 노출하지 않는 것이 원칙입니다.
기본 동작 확인
H2 의존성만 추가하면 스프링 부트가 다음을 자동으로 수행합니다.
DataSource빈을jdbc:h2:mem:<임의UUID>URL로 생성- JPA가 활성화돼 있으면
spring.jpa.hibernate.ddl-auto=create-drop으로 동작 spring.h2.console.enabled=true일 때/h2-console경로에 웹 UI 노출
// Entity가 있으면 기동 시 CREATE TABLE이 자동 실행됨
@Entity
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String email;
private String name;
}
설정 파일 구성
H2 관련 핵심 설정을 정리합니다.
# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
path: /h2-console
settings:
web-allow-others: false # 원격 접속 차단
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create-drop
show-sql: true
주요 JDBC URL 옵션 설명입니다.
| 옵션 | 의미 |
|---|---|
MODE=MySQL | MySQL 문법 호환 (AUTO_INCREMENT, LIMIT 등) |
DB_CLOSE_DELAY=-1 | 마지막 커넥션이 닫혀도 DB 유지 |
DB_CLOSE_ON_EXIT=FALSE | JVM 종료 시 자동 닫기 비활성화 |
H2 웹 콘솔 사용법
앱을 기동한 뒤 브라우저에서 http://localhost:8080/h2-console에 접속합니다.
접속 화면에서 입력할 내용입니다.
Driver Class: org.h2.Driver
JDBC URL: jdbc:h2:mem:testdb
User Name: sa
Password: (비워둠)
JDBC URL은 application.yml의 spring.datasource.url과 정확히 일치해야 합니다. URL이 다르면 다른 인메모리 인스턴스에 연결되어 아무 테이블도 보이지 않습니다.
Spring Security와 충돌 해결
spring-boot-starter-security가 추가돼 있으면 /h2-console이 차단됩니다. H2 콘솔은 iframe 기반 UI라 추가 이슈도 있습니다.
// 개발 환경 전용 Security 설정
@Profile("dev")
@Configuration
public class H2SecurityConfig {
@Bean
@Order(1)
public SecurityFilterChain h2ConsoleFilterChain(
HttpSecurity http) throws Exception {
return http
.securityMatcher("/h2-console/**")
.authorizeHttpRequests(auth ->
auth.anyRequest().permitAll())
.csrf(csrf -> csrf.disable())
.headers(headers -> headers
.frameOptions(frame -> frame.disable()))
.build();
}
}
@Profile("dev")로 감싸면 prod 환경에서는 이 빈 자체가 생성되지 않으므로 안전합니다.
초기 데이터 설정
schema.sql + data.sql
src/main/resources/에 파일을 두면 기동 시 자동 실행됩니다.
-- schema.sql (테이블 정의)
CREATE TABLE IF NOT EXISTS category (
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL
);
-- data.sql (초기 데이터)
INSERT INTO category (id, name) VALUES (1, 'ELECTRONICS');
INSERT INTO category (id, name) VALUES (2, 'CLOTHING');
스프링 부트 2.5 이후로 JPA DDL 자동 실행 이후에 data.sql이 실행됩니다. 순서를 명확히 하려면 다음 설정을 추가합니다.
spring:
jpa:
defer-datasource-initialization: true
@Sql 어노테이션으로 테스트별 데이터 제어
@SpringBootTest
@Sql(scripts = "/sql/test-users.sql",
executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql",
executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
class UserServiceTest {
@Autowired
private UserService userService;
@Test
void 사용자_목록_조회() {
List<User> users = userService.findAll();
assertThat(users).hasSize(3);
}
}
H2 콘솔 동작 구조
H2는 JVM 내부에서 동작하므로 별도 프로세스 간 통신이 없고, 같은 JVM 내의 여러 커넥션이 동일한 인메모리 DB를 공유합니다. 앱 코드와 웹 콘솔이 같은 DB를 보는 이유입니다.
파일 모드 H2 (데이터 영속)
인메모리 모드 대신 파일에 저장하면 재기동 후에도 데이터가 유지됩니다.
spring:
datasource:
url: jdbc:h2:file:./data/testdb;MODE=MySQL
로컬 개발에서 외부 MySQL을 실행하지 않고도 어느 정도의 영속성을 유지하고 싶을 때 사용합니다. .gitignore에 data/ 디렉터리를 추가하는 것을 잊지 마세요.
프로파일 전략 정리
H2는 개발·테스트에만 사용하고, 실제 운영 환경에서는 MySQL·PostgreSQL 등 실제 RDBMS를 사용합니다. 프로파일로 분리하는 것이 핵심입니다.
# application.yml (기본 — prod용)
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
h2:
console:
enabled: false
# application-dev.yml (개발용)
spring:
datasource:
url: jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1
driver-class-name: org.h2.Driver
h2:
console:
enabled: true
./gradlew bootRun --args='--spring.profiles.active=dev'로 기동하면 H2가 활성화됩니다. IDE에서는 Run Configuration의 VM options에 -Dspring.profiles.active=dev를 추가합니다.
지난 글: Spring Boot Flyway & Liquibase — DB 마이그레이션 자동화
다음 글: Spring Boot 쿼리 로깅 — SQL·파라미터·성능 측정
읽어주셔서 감사합니다. 😊