Embedded 데이터베이스
1. Dependency
build.gradle
runtimeOnly 'com.h2database:h2'
2. Configuration
application.yml
spring.h2.console.enabled: true
3. h2 접속
해당 주소로 h2 console에 접근합니다.
localhost:8080/h2-console
스프링부트는 내부적으로 아래와 같은 설정을 자동으로 합니다.
그러므로 화면과 똑같은 값이 있는지 확인하셔야 합니다.
- Driver Class : org.h2.Driver
- JDBC URL : jdbc:h2:mem:testdb
- Username : sa
- Password :
4. 로그 설정
application.yml
logging.level.org.hibernate.SQL: debug # 로그 형식으로 쿼리 보여주기
spring.jpa.properties.hibernate.format_sql: true # 압축된 쿼리를 읽기 좋게 포멧
spring.jpa.hibernate.ddl-auto: create # 서버 시작에 테이블 생성
spring.jpa.hibernate.ddl-auto
- create : 서버 시작에 모든 테이블 생성
- create-drop : 서버 시작에 모든 테이블 생성, 서버 종료에 테이블 삭제
- update : 서버 시작에 변경된 내용 반영. 테이블이 없으면 생성
- validate : 서버 시작에 엔티티와 테이블 비교, 다르면 종료
- none : 아무 처리하지 않음
build.gradle
implementation "com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.6.1" // 쿼리의 실제 파라미터 보여주기
로컬에서 실행하기
1. 저장한 설정
저장한 설정을 Generice H2 (Server)
로 변경한다. 이제 tcp 통신을 통해 로컬의 test라는 데이터베이스에 저장되게 된다
2. Mac 사용자의 경우
맥을 사용할 경우 test 데이터베이스가 없다는 에러가 생길 경우가 있습니다. 이는 MAC OS 버전이 Catalina인 경우 발생할 수 있습니다. 이 경우 JDBC URL을 jdbc:h2:~/test
로 바꿔줍니다. 그리고 접속을 하면 /User/사용자/
경로 아래 test
라는 데이터베이스가 생성됩니다. 재시작 이후 JDBC URL을 jdbc:h2:tcp://localhost/~/test
로 바꾸면 사용가능 합니다.
참고. 발생 가능한 이슈
첫번째. Database "mem:testdb" not found, either pre-create it or allow remote database creation (not recommended in secure environments)
문제점
내용을 살펴보면 mem:testdb라는 데이터베이스를 찾을 수 없다고 나옵니다. 혹은 데이터베이스를 미리 생성(pre-create) 할 수도 없다고 나옵니다. 혹은 원격 데이터 생성도 할 수 없다고 나옵니다. 데이터베이스를 보안상의 이유로 생성을 못하게 h2 기본 설정 자체에서 막아놓을 것으로 보입니다.
원인
조금 찾아본 결과 이곳에서 문제의 원인을 찾을 수 있었습니다. h2가 1.4.197
과 1.4.198
버전 사이에 대규모 업데이트가 되면서 데이터베이스를 미리 생성하는 것을 방지하도록 설정되었습니다.
해결책
- h2의 버전을
1.4.198
보다 낮은 버전으로 설정
runtimeOnly 'com.h2database:h2:1.4.197'
- 데이터베이스 생성
기존에 생성해주는 데이터베이스가 없으므로 직접 데이터베이스를 생성할 수 있습니다. 해당 내용은1.4.197
이하 버전에서는 스프링부트가 h2를 classpath에서 발견하면 자동적으로 설정되는 내용입니다. 그러므로 해당 버전을 사용한다면 아래 내용이 내부적으로 설정되어 있습니다.
application.yml
spring.datasource.url: jdbc:h2:mem:testdb
spring.datasource.driverClassName: org.h2.Driver
spring.datasource.username: sa
spring.datasource.password:
spring.jpa.database-platform: org.hibernate.dialect.H2Dialect
두번째. 403 forbidden
문제점
스프링 서큐리티를 사용할 때 403(접속 권한) 오류가 발생합니다.
원인
스프링 서큐리티에서 아래와 같은 내용을 설정해주셔야 합니다.
- csrf disable
- X-Frame-Options disable
/h2-console
허용
해결책
@EnableWebSecurity
@Configuration
public class OAuthConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.headers().frameOptions().disable()
.and()
.authorizeRequests()
.antMatchers("/h2-console/**")
.permitAll();
}
}
인텔리제이에서 Datasource 연결
org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "CATALOGS" not found 에러
인텔리제이에서 h2 연결 시 발생하는 문제입니다.
현재 사용하는 h2는 2.1.214 (2022.11.3 최신버전)을 사용하면서 발생한 에러입니다.
원인을 검색하던 결과 이곳에서 해결법을 찾을 수 있었습니다
해당 이슈는 인텔리제이가 h2 접속시 초기 데이터를 fetch 하면서 발생하는 에러입니다
SELECT CATALOG_NAME FROM INFORMATION_SCHEMA.CATALOGS
하지만 해당 테이블은 h2 1.4.200
이하 버전에만 존재하는 테이블입니다.
이 경우 OLD_INFORMATION_SCHEMA=TRUE
옵션을 url 마지막에 붙혀주시면 됩니다
jdbc:h2:tcp://localhost/~/h2/2.1.214/db/test;OLD_INFORMATION_SCHEMA=TRUE
접속 이후 INFORMATION_SCHEMA 데이터베이스를 확인해보시면 CATALOGS 테이블이 존재함을 볼 수 있습니다