H2 데이터베이스는
간단한 프로젝트나 테스트용으로
적합한 데이터베이스이다.
H2의 장점은 Embeded모드를
지원하기 때문이다.
Application과 DB의 통신
Oracle , MySQL, MariaDB의 작동원리는 위 그림과 같다.
Application에서 DB에 read/write 하려면, DBMS와 맞는 JDBC 라이브러리를 설치하여 TCP/IP 통신을 해야한다. 이와같이, Application과 DBMS가 독립된 프로세스로 분리되어 있으면 DBMS는 많은 기능을 제공할 수 있다.
하지만 반대급부로 설정이 어려워지고 무거워진다. 개발자는 DB를 설치 및 설정해야 하고 프로세스를 유지해야 한다. 또한 App과 DBMS는 독립된 프로세스이기에 '통신' 과정이 수반된다. 그러므로 속도도 느리다. 실운영 환경이면 이런 단점쯤은 고려사항이 되지 않지만 간단한 프로젝트나 단위테스트를 할 때는 무겁고, 느리고, 어려운 방식은 비효율이다.
H2 데이터베이스의 장점은 여기서 나타난다. H2 데이터베이스는 Embeded모드를 지원한다.
Embeded
H2는 2가지 모드를 지원한다.
1. Embeded 모드
2. Server 모드
H2가 다른 DB와 차별된 점은 Embeded모드이다. SpringBoot로 프로젝트를 하나 생성해보겠다. ( https://start.spring.io/ )
> 스프링부트 버전 : 3.0.5
SpringWEB, Lombok, JPA 그리고 h2를 디펜던시로 추가했다. 간단하게 회원정보를 DB에 저장하는 과정을 구현해보겠다. Member클래스를 만들고 MemberRepository 클래스로 DB에 저장하고 다시 조회하는 코드이다. Junit5로 테스트 클래스를 만들어서 테스트해보았다. JPA 문법이 사용되었지만 문법을 몰라도 충분히 이해가능하다.
Member 클래스
package com.example.demo;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
private Long id;
private String username;
}
MemberRepository클래스
package com.example.demo;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
@Repository
public class MemberRepository {
@PersistenceContext
EntityManager em;
// DB에 member 저장
public Long save(Member member){
em.persist(member);
return member.getId();
}
// DB에서 member 조회
public Member find(Long id){
return em.find(Member.class,id);
}
}
Junit5 단위테스트
package com.example.demo;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
@ExtendWith(SpringExtension.class)
@SpringBootTest
@Transactional
public class MemberRepositoryTest {
@Autowired MemberRepository memberRepository;
@Test
@Transactional
@Rollback(value = false) // 커밋과 같은 의미
public void testMember(){
//회원 생성
Member member = new Member();
member.setUsername("강민구");
//회원정보 DB에 삽입하기
Long saveId = memberRepository.save(member);
//회원정보 조회하기
Member findMember = memberRepository.find(saveId);
//테스트 ( 삽입데이터와 조회데이터가 일치하는지 확인 )
Assertions.assertThat(findMember.getId()).isEqualTo(member.getId());
Assertions.assertThat(findMember.getUsername()).isEqualTo((member.getUsername()));
Assertions.assertThat(findMember).isEqualTo(member);
}
}
DB에 회원정보를 삽입하고 삽입한 데이터를 다시 조회한다. 그리고 삽입데이터와 조회데이터가 일치하는지 확인한다. 만약 기존방식이었다면 DB를 설치하고 테이블을 생성하고 DBMS를 실행시키는 등의 각종 설정을 해야한다. 그러나 h2 Embeded모드는 한 가지 설정만 넣어주면 된다.
src/main/resources/application.yml
spring: #띄어쓰기 없음
datasource: #띄어쓰기 2칸
url: jdbc:h2:~/h2test2 #띄어쓰기 4칸
username: sa
password:
driver-class-name: org.h2.Driver
jpa: #띄어쓰기 2칸
hibernate: #띄어쓰기 4칸
ddl-auto: create #띄어쓰기 6칸
properties: #띄어쓰기 4칸
hibernate: #띄어쓰기 6칸
#show_sql: true #띄어쓰기 8칸
format_sql: true #띄어쓰기 8칸
logging.level: #띄어쓰기 없음
org.hibernate.SQL: debug #띄어쓰기 2칸
org.hibernate.orm.jdbc.bind: trace
# org.hibernate.type: trace #띄어쓰기 2칸
( 띄어쓰기 유의! )
datasource 설정을 위 파일과 같이 넣어준다. jdbc드라이버는 h2드라이버이고 url을 넣어주면 그 위치에 [입력한 파일명].mv.db 파일이 생성된다. mv.db 파일은 DB정보, 테이블과 삽입된 데이터 정보를 저장된 파일이다. 이렇게 위 설정만 넣으면 끝이다.
그냥 JAVA 코드 짜고 설정 하나 넣어주면 끝이다.
JVM이 알아서 H2 실행시키고 H2는 mv.db 파일 만들어 DB 정보 유지하고 관리한다.
JVM 프로세스 하나에 Application과 h2 db가 모두 동작하는 것이다. 하나의 프로세스에서 동작하면 메모리 및 cpu를 공유하므로 속도도 빠르다. 따로 TCP 통신을 할 필요가 없어진다.
단위테스트를 실행하면 아래와 같은 결과를 얻는다.
SQL 쿼리문이 실행되었음을 로그를 통해 확인 가능하다. SQL문 관련해서는 JPA와 관련되므로 해당 포스팅에서는 다루지 않겠다.
위 그림 같이, 정해진 경로에 mv.db 파일이 생성되었음도 확인 가능하다. DB설치 없이 그저 h2 라이브러리만 디펜던시로 추가했을 뿐인데 테이블 생성과 더불어 데이터 삽입 및 조회도 가능해졌다. 그럼 H2 프로그램을 설치하여 콘솔을 통해 눈으로 확인해보자.
위 사이트에서 설치를 하고 압축을 해제한다. 그리고 h2 폴더에서 bin폴더로 이동한다.
Mac인 경우, 터미널에서 > sh h2.sh로 실행시키면되고 윈도우는 h2.bat을 실행시키면 된다.
그럼 위 창이 자동으로 실행된다. H2를 Embeded로 바꾸고 application.yml과 동일하게 설정한다. 그리고 연결한다.
MEMBER 테이블이 생성되고 데이터가 삽입되어 있음을 확인할 수 있다.
정리
이처럼 H2 데이터베이스는 Embeded 모드를 제공하기에 JAVA 코드만으로 DB에 데이터를 read/write 할 수 있다. mv.db를 Application과 함께 빌드배포하면 다른 환경에서 자동으로 DB구성도 할 수 있다. 물론 복잡한 기능을 제공하지 못하여 실운영에서 적합하지 않을 수 있지만 간단히 테스트를 하거나 작은 프로젝트를 진행하는데 간편하게 사용할 수 있다.