Table of contents
스프링부트가 지원하는 인메모리 데이터베이스에 대해 알아보자.
인메모리 데이터베이스
인메모리 데이터베이스는 말 그대로 애플리케이션 서버의 메모리를 이용하는 데이터베이스 시스템을 말한다.
지원하는 데이터베이스의 종류는 다음과 같다.
- H2
- HSQL
- Derby
실습
스프링부트에서 스프링 JDBC 의존성이 클래스패스에 있는 경우, DataSource와 JdbcTemplate이 자동 설정된다. (DataSourceAutoConfiguration와 JdbcTemplateAutoConfiguration에서 확인이 가능하다)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
h2 의존성이 클래스패스에 있고, DataSource에 대한 아무런 설정도 하지 않았다면 스프링부트가 자동으로 h2를 인메모리 데이터베이스를 설정한다.
ApplicationRunner를 이용해 DataSource의 정보를 확인해보자.
@Component
public class H2Runner implements ApplicationRunner {
@Autowired
DataSource dataSource;
@Override
public void run(ApplicationArguments args) throws Exception {
Connection connection = dataSource.getConnection();
System.out.println("===============");
System.out.println(connection.getMetaData().getURL());
System.out.println(connection.getMetaData().getUserName());
}
}
H2Ruuner를 작성하고 빈으로 등록한 뒤 앱을 실행하면 URL은 "jdbc:h2:mem:testdb", userName은 "SA"가 출력된다. 이런 정보는 DataSourceAutoConfiguration에서 자동으로 설정한다. 해당 클래스에서 EmbeddedDatabaseConfiguration를 등록하는 부분을 보면, EmbeddedDataSourceConfiguration를 import하는 것을 알 수 있다. EmbeddedDataSourceConfiguration의 코드를 열어보자.
@Bean
public EmbeddedDatabase dataSource() {
this.database = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseConnection.get(this.classLoader).getType())
.setName(this.properties.determineDatabaseName()).build();
return this.database;
}
EmbeddedDataSourceConfiguration가 DataSource를 등록하는 것을 알 수 있다. EmbeddedDataSourceConfiguration는 생성자에서 DataSourceProperties를 properties라는 인스턴스 변수로 주입받는다. DataSourceProperties는 이름에서 알 수 있듯이, DataSource의 프로퍼티에 관련된 클래스로서 dbname, url, userName 등을 결정하거나 반환한다.
다시 실습으로 돌아와서, 러너에서 테이블을 만들어보자.
@Component
public class H2Runner implements ApplicationRunner {
@Autowired
DataSource dataSource;
@Override
public void run(ApplicationArguments args) throws Exception {
try (Connection connection = dataSource.getConnection()) {
System.out.println("===============");
System.out.println(connection.getMetaData().getURL());
System.out.println(connection.getMetaData().getUserName());
Statement statement = connection.createStatement();
String sql = "CREATE TABLE USER(ID INTEGER NOT NULL, name VARCHAR(255), PRIMARY KEY (id))";
statement.executeUpdate(sql);
}
}
}
JDBC를 이용해 USER 테이블을 만드는 코드를 작성하고 (트랜잭션, 롤백과 같은 세부사항은 제외) 앱을 실행하면 정상적으로 동작하는 것을 알 수 있다. H2가 제공하는 콘솔을 이용해 USER 테이블이 생성되었는지 확인해보자.
H2 콘솔
spring-boot-devtools를 추가하거나 spring.h2.console.enabled=true를 추가하면 H2 콘솔을 사용할 수 있다. application.properties에 spring.h2.console.enabled=true를 추가하고 /h2-console로 접속해보자. (해당 경로는 변경할 수 있다)
웹콘솔에 접속한 뒤, 연결정보(jdbc:h2:mem:testdb, sa)를 입력하고 connect 버튼을 클릭하면 콘솔화면이 나타난다. 정상적으로 접속되었다면 USER 테이블이 생성되어있는 것을 볼 수 있다.
이번에는 JdbcTemplate를 이용하여 INSERT 쿼리를 실행해보자. 좀 더 간결하고 안전하게 쿼리를 작성할 수 있다.
@Override
public void run(ApplicationArguments args) throws Exception {
try (Connection connection = dataSource.getConnection()) {
System.out.println("===============");
System.out.println(connection.getMetaData().getURL());
System.out.println(connection.getMetaData().getUserName());
Statement statement = connection.createStatement();
String sql = "CREATE TABLE USER(ID INTEGER NOT NULL, name VARCHAR(255), PRIMARY KEY (id))";
statement.executeUpdate(sql);
}
jdbcTemplate.execute("INSERT INTO USER VALUES (1, 'jch')");
}
앱을 재구동하여 콘솔에서 SELECT 쿼리로 확인해보면 추가된 사용자 정보를 조회할 수 있다.
JdbcTemplate를 이용하면 리소스 반납 처리, 계층구조가 잘 잘 구성되어 가독성 높은 예외를 사용하는 등의 장점을 누릴 수 있다.
해당 포스팅은 스프링 부트 개념과 활용 강의 내용을 토대로 작성하였습니다.