H2 Database
H2 In-Memory Database
H2 is a lightweight embedded database that runs in memory. It's ideal for:
- Development — no need to install an external database
- Testing — every test starts from a clean state
- Prototyping — build and run the application quickly
H2 supports in-memory mode and file-based mode. For Spring Boot, we focus on in-memory mode.
Configuration in application.properties
Add the dependency in pom.xml:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Configuration in application.properties:
# H2 Database
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
# H2 Console
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# JPA / Hibernate
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.show-sql=true
Property explanation:
| Property | Value | Description |
|---|---|---|
spring.datasource.url |
jdbc:h2:mem:testdb |
In-memory database named testdb |
spring.h2.console.enabled |
true |
Enable the web console |
spring.h2.console.path |
/h2-console |
Path to access the console |
spring.jpa.hibernate.ddl-auto |
create-drop |
Create the schema at startup, drop it at shutdown |
spring.jpa.show-sql |
true |
Log SQL to the console |
H2 Console
Once the application is running, open the H2 Console in your browser:
http://localhost:8080/h2-console
On the H2 Console login page:
- JDBC URL:
jdbc:h2:mem:testdb - User Name:
sa - Password: (empty)
- Click Connect
You can run SQL directly in the console:
SELECT * FROM users;
INSERT INTO users (name, email) VALUES ('John', '[email protected]');
SHOW TABLES;
data.sql for Seed Data
Spring Boot automatically runs data.sql at startup if the file exists on the classpath:
-- data.sql (in src/main/resources/)
INSERT INTO users (name, email, created_at) VALUES
('Mike', '[email protected]', CURRENT_TIMESTAMP),
('John', '[email protected]', CURRENT_TIMESTAMP),
('Anna', '[email protected]', CURRENT_TIMESTAMP);
INSERT INTO products (name, price, stock) VALUES
('Laptop', 12000000, 10),
('Mouse', 150000, 50),
('Keyboard', 350000, 30);
Execution order: schema.sql → data.sql
-- schema.sql (optional, Hibernate usually handles this)
CREATE TABLE IF NOT EXISTS users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Spring Boot DevTools + H2
DevTools provides an automatic restart when the code changes:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
When using H2 in-memory + DevTools, you need to be careful:
# So H2 isn't reset when devtools triggers a restart
spring.h2.console.enabled=true
# or disable devtools restart for certain classes
spring.devtools.restart.exclude=static/**,public/**
Configuration for Testing
Use a separate profile for tests:
# application-test.properties
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.jpa.hibernate.ddl-auto=create-drop
spring.h2.console.enabled=false
@SpringBootTest
@ActiveProfiles("test")
class UserRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
void shouldSaveUser() {
User user = new User();
user.setName("Test User");
user.setEmail("[email protected]");
User saved = userRepository.save(user);
assertThat(saved.getId()).isNotNull();
assertThat(saved.getName()).isEqualTo("Test User");
}
}
H2 for Development vs Production
┌─────────────────────┬──────────────┬──────────────────┐
│ Aspect │ H2 In-Memory │ MySQL/PostgreSQL │
├─────────────────────┼──────────────┼──────────────────┤
│ Setup Speed │ Instant │ Requires install │
│ Performance │ Adequate │ Better │
│ Persistence │ Lost on │ Persistent │
│ │ restart │ │
│ SQL Features │ Basic │ Full │
│ Best For │ Dev/Test │ Production │
│ Concurrent Access │ Limited │ Full │
└─────────────────────┴──────────────┴──────────────────┘
H2 is very helpful during development and testing. But for production, you need a real database. In the next chapter, we'll configure MySQL and PostgreSQL for production.