[데브코스] JDBC 3

Updated: Categories:

W4D4 - Embedded Database / NamedParameter JDBC Template / Transaction 에 대해 공부해보자!

Embedded Database

  • 외부 요인에 따라 테스트가 불가능한 상황이 있을 수 있다 (MySQL이 꺼져있거나..)
  • 따라서 Spring에서는 시스템 내부에서 돌아가는 Embedded Database를 제공한다.
  • 테스트 DB와 실제사용 DB를 분리하여 사용하는것


H2

  • 자바 기반 오픈소스 RDBMS
  • in-memory 데이터 스토리의 메인 메모리에 설치되어 운영된다
  • 테스트용 DB이므로 매우 가볍다.
  • 단 다른 종류의 DBMS의 SQL 문법을 지원하지 않는다.

사용법

  • pom.xml dependency에 h2 database를 추가해준다
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>
  • DataSource Bean에 연결 정보 정의하기
@Bean
public DataSource dataSource() {
    // Datasource를 상속받으므로 바로 리턴
    return new EmbeddedDatabaseBuilder()
            .generateUniqueName(true)
            .setType(H2)
            .setScriptEncoding("UTF-8")
            .ignoreFailedDrops(true)
            .addScript("schema.sql")    // resources 하위에 sql 파일을 정의해줘야함
            .build();
}


Embedded MySQL

  • 만약 연동 DB가 MySQL이라 쿼리문에 MySQL 전용 문법이 사용되었다면?
    • -> H2와는 쿼리문이 연동되지 않음 -> Embedded MySQL을 사용해야함

사용법

  • pom.xml dependency에 Embedded MySQL을 추가해준다
<dependency>
	<groupId>com.wix</groupId>
	<artifactId>wix-embedded-mysql</artifactId>
	<version>4.6.1</version>
	<scope>test</scope>
</dependency>
  • 모듈사용법은 여기를 참고
  • mysql config -> 접속정보 + 테스트용 DB를 만들고 시작한다
  • 이 접속 정보를 가지고 DataSource Bean에 정의해주자
var mysqlConfig = aMysqldConfig(버전)  
        .withCharset(UTF8)
        .withPort(2215)                 
        .withUser(호스트명, 비번)      
        .withTimeZone("Asia/Seoul")
        .build();

anEmbeddedMysql(mysqlConfig)
        .addSchema(DB명), classPathScript("schema.sql"))    // resources 하위에 sql 파일을 정의해줘야함
        .start();

오류

image

  • 매우 화가난다 v8_0_11로 실행하니 이런 오류가 뜨면서 실행이 안됨
  • 여기를 참고하니… 윈도우에서 C++ 패카지가 설치되어 있지 않을때 발생하는 오류라고 함
    • 나는 깔려있는데도 오류가 뜬다. 해결불가..


NamedParameter JDBC Template

  • NamedParameterJdbcTemplate 타입으로 jdbc 템플릿을 생성한다.
  • 기존 jdbc 템플릿의 메소드는 인자값을 직접 매핑해서 넣어줘야 했지만, NamedParameter 템플릿은 Map의 key를 이용해 넣는다.
  • 미리 ParamMap<call key, mapping v>로 정의해두고, 쿼리에서는 :key로 호출한다
    • 인자값을 순서에 맞춰 넣을 때의 실수를 줄이기 위해 사용!

메소드

// 일반 JdbcTemplate과 리턴값은 동일하지만 인자값이 다르다.
namedParameterJdbcTemplate.query(쿼리, RowMapper)
namedParameterJdbcTemplate.queryForObject(쿼리, ParamMap, RowMapper)
namedParameterJdbcTemplate.update(쿼리, ParamMap, Integer.class)


Transaction

  • 트랜잭션 기본 개념 - 🚀 포스팅 이동
  • JDBC에서 오토 커밋 default 값은 true이므로… -> 쿼리가 트랜잭션으로 묶여서 실행되지 않음
  • 따라서 connection.setAutoCommit(false)로 오토 커밋을 꺼주고 commit과 rollback을 적용해 트랜잭션을 구현한다.

기본 flow 예제

...
    // 오토 커밋을 풀어서 커밋 전까지는 하나의 트랜잭션으로 묶이게 만든다
    connection.setAutoCommit(false);
    ...
    쿼리 실행
    ...
    connection.setAutoCommit(true);
} catch(에러) {
    // 에러 발생시 롤백 시켜줌
    connection.rollback();
    connection.close();
}