spring boot multiple database

seanical·2022년 4월 12일
0

현업에서는 여러가지의 데이터베이스를 연결해야하는일이 굉장히 많다.
Properties를 통한 두개 이상의 데이터베이스를 연결하려면 어떻게 해야할까?

mysql, h2 database를 사용하여 Member객체를 insert 하는 예제를 들어보겠습니다.

  1. Build.gradle 설정

build.gradle 코드

plugins {
	id 'org.springframework.boot' version '2.6.6'
	id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'hello'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'mysql:mysql-connector-java'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}

사실 다른것은 중요한게 아니고 h2, mysql 을 사용하려면 dependencies에 있는것들을 추가해주면 된다.

  1. application.yaml 추가
    java/resources 폴더 아래application.yaml을 생성하고 다음 아래의 값들을 채워준다.

application.yaml 코드

spring:
  profiles:
    active: dev
---
spring:
  datasource:
    jdbc-url: jdbc:h2:tcp://localhost/~/test
    driver-class-name: org.h2.Driver
    username: sa
    password:

  datasource-mysql:
    jdbc-url:  jdbc:mysql://localhost:3306/streaming?serverTimezone=UTC&characterEncoding=UTF-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 1234

  config:
    activate:
      on-profile: "dev"

현업에서는 dev, sandbox, prod, local 같은 Profile을 나눠 환경설정을 하기때문에 다음과 같이 나타내었고 dev 환경에서 datasource를 어떻게 쓰겠다 정의한것이다.

  1. DataSourceConfig 생성

DataSourceConfing 코드

package hello.springboot.config;

import com.zaxxer.hikari.HikariDataSource;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;


@Configuration
public class DataSourceConfig {

    @Profile("dev")
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public HikariDataSource h2dataSource(){
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Profile("dev")
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource-mysql")
    public HikariDataSource mySqldataSource(){
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

}

내가 원하는 데이터소스를 정의를 합니다.
HikariDatasource는 데이터베이스를 의미하는게 아니라 h2, mysqlconnection을 도와주는 것이라고 생각하면된다.

  • @Profile("dev")
    위에서 작성한 어떠한 환경(dev)일때 돌아가는지 @Profile("dev")로 표시한것이다.
    현재 환경은 dev라고 application.yaml에 아래와같이 정의하여 현재 dev환경에서 아래 Bean등록을 시도할것이다.
spring:
  profiles:
    active: dev
  • @Bean
    스프링 컨테이너 Bean저장소에 Bean으로 등록할것이다라는 예약어

  • @ConfigurationProperties(prefix = "spring.datasource")

    @ConfigurationProperties(prefix = "spring.datasource")의 의미는
    application.yaml파일의 spring > datasource 아래있는 내용들을 주입할겁니다. 라고 약속하는것이다.
    따라서 DataSourceBuilder.create().type(HikariDataSource.class).build();

    에 데이터베이스의 정보를 적어주지 않아도 위의 h2 데이터베이스 설정값들이 주입되어 h2dataSource라는 이름의 객체가 Bean으로 등록된다.

  1. Member Domain 객체 추가

Member 코드

@Getter
@Setter
public class Member {

    private Long id;
    private String name;

    public Member(Long id, String name) {
        this.id = id;
        this.name = name;
    }
}
  1. MemberRepository 추가

MemberRepository 코드

package hello.springboot.repository;

import com.zaxxer.hikari.HikariDataSource;
import hello.springboot.domain.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;

@Repository
public class MemberRepository {

    private HikariDataSource dataSource;
    private JdbcTemplate jdbcTemplate;

    public HikariDataSource getDataSource() {
        return dataSource;
    }

    public MemberRepository(@Qualifier("mySqldataSource") HikariDataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcTemplate = new JdbcTemplate(this.dataSource);
    }

    public void insert(Member member){
        jdbcTemplate.update("INSERT INTO MEMBER(NAME) VALUES (?)",member.getName());
    }


}

실제 쿼리를 날리기위해 Repository를 간단히 만들어주고 정의한 datasource 중 원하는 datasource주입시켜준다.

    public MemberRepository(@Qualifier("mySqldataSource") HikariDataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcTemplate = new JdbcTemplate(this.dataSource);
    }

3번의 DatasourceConfig에서는 HikariDataSource 타입으로 갖는 Bean이 두가지 h2dataSource , mySqldataSource 존재한다.
여기서 선택적으로 판단하기위해 @Qualifier 어노테이션으로 위의 문제를 해결 할 수 있다.

  1. 테스트코드 작성

테스트코드

package hello.springboot.config;

import hello.springboot.domain.Member;
import hello.springboot.repository.MemberRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

@SpringBootTest
@ActiveProfiles("dev")
public class DatasourceConfigTest {

    @Autowired
    private MemberRepository memberRepository;

    @Test
    @DisplayName("insert 테스트")
    void insertTest() {
        Member member = new Member(1L,"sean");
        memberRepository.insert(member);
    }
}

dev 환경이라고 @ActiveProfiles("dev")로 명시하고
@Repository로 등록된 MemberRepositoryBean세팅은 우리가 원한대로 이루어져있다.
아래 코드를 실행하면 제대로 값이 들어간것을 확인 할 수있다.


현재 데이터베이스는 @Qualifier("mySqldataSource")Mysql로 잡혀있지만
h2로 변경을 원하면 @Qualifier("h2dataSource")로만 변경하면된다.

0개의 댓글