daangn-daangn / daangn-server

🥕당근 서버 리포지토리🥕
4 stars 2 forks source link

multi-datasource Bean으로 전환 #73

Closed cotchan closed 2 years ago

cotchan commented 2 years ago

작업 목적

작업 내용 목차

  1. 작업내용1 링크
  2. 작업내용2 링크
cotchan commented 2 years ago

작업내용1

rdb(MYSQL) - JavaConfig로 Datasource 설정 작업

목차

  1. JavaConfig에 application.yml 설정값 주입하여 dataSource 빈 직접 생성
    • 수정사항1
    • 수정사항2
    • 수정사항3(CamelCase에서 SnakeCase 변환)
  2. JavaConfig 설정
    • @EnableJpaRepositories
    • DataSource와 JpaProperties
    • LocalContainerEntityManagerFactoryBean
    • PlatformTransactionManager

JavaConfig에 application.yml 설정값 주입하여 dataSource 빈 직접 생성

수정사항1

spring:
  datasource:
    hikari:
      driver-class-name: org.h2.Driver
      jdbc-url: jdbc:h2:tcp://localhost/~/daangn;MODE=MYSQL;
      username: sa
      password:

수정사항2

수정사항3(CamelCase에서 SnakeCase 변환)

spring:
  jpa:
    properties:
      hibernate:
        implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
        physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

JavaConfig 설정

package com.daangndaangn.common.configure;

import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration // Configuration 클래스임을 명시
@EnableJpaRepositories(
    basePackages = "com.daangndaangn.common.api.repository", // 해당 DataSource를 적용할 패키지 경로, 해당 패키지가 적용될 repository
    entityManagerFactoryRef = "apiEntityManager",            // 해당 TransactionEntityManagerFactory가 사용할 메소드명
    transactionManagerRef = "apiTransactionManager"          // 해당 TransactinoManager가 참조할 메소드 명
)
public class ApiDbConfigure {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource apiDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.jpa")
    public JpaProperties jpaProperties() {
        return new JpaProperties();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean apiEntityManager(EntityManagerFactoryBuilder builder,
                                                                   DataSource dataSource,
                                                                   JpaProperties jpaProperties) {
        return builder
                .dataSource(dataSource)
                .properties(jpaProperties.getProperties())
                .packages("com.daangndaangn.common.api.entity")
                .persistenceUnit("default")
                .build();
    }

    @Primary
    @Bean(name = "apiTransactionManager")
    public PlatformTransactionManager apiTransactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager(entityManagerFactory.getObject());
        return transactionManager;
    }
}

@EnableJpaRepositories

DataSource와 JpaProperties

@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public DataSource apiDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
@ConfigurationProperties(prefix = "spring.jpa")
public JpaProperties jpaProperties() {
    return new JpaProperties();
}

LocalContainerEntityManagerFactoryBean

@Bean
public LocalContainerEntityManagerFactoryBean apiEntityManager(EntityManagerFactoryBuilder builder,
                                                               DataSource dataSource,
                                                               JpaProperties jpaProperties) {

    return builder
            .dataSource(dataSource)
            .properties(jpaProperties.getProperties())
            .packages("com.daangndaangn.common.api.entity")
            .persistenceUnit("default")
            .build();
}

PlatformTransactionManager

@Bean(name = "apiTransactionManager")
public PlatformTransactionManager apiTransactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
    JpaTransactionManager transactionManager = new JpaTransactionManager(entityManagerFactory.getObject());
    return transactionManager;
}

cotchan commented 2 years ago

작업내용2

Spring Data MongoDB TransactionManager 설정

목차

  1. MongoTransactionManager 적용이유
  2. Replica-Set
  3. MongoConfig class

MongoTransactionManager 적용이유

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
}

Replica-Set

$ mongod --dbpath=/Users/Chanyoung/data/db --replSet rs

// 몽고DB 접근 시
$ mongo

MongoConfig class

@Configuration
@EnableMongoRepositories(
    basePackages = "com.daangndaangn.common.chat.repository"
)
public class MongoDbConfigure extends AbstractMongoClientConfiguration {

    @Bean(name="mongoTransactionManager")
    public MongoTransactionManager mongoTransactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

    @Override
    protected String getDatabaseName() {
        return "daangn_test";
    }
}
@Configuration
@EnableMongoRepositories(basePackages = "com.baeldung.repository")
public class MongoConfig extends AbstractMongoClientConfiguration{

    @Bean
    MongoTransactionManager transactionManager(MongoDatabaseFactory dbFactory) {
        return new MongoTransactionManager(dbFactory);
    }

    @Override
    protected String getDatabaseName() {
        return "test";
    }

    @Override
    public MongoClient mongoClient() {
        final ConnectionString connectionString = new ConnectionString("mongodb://localhost:27017/test");
        final MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
            .applyConnectionString(connectionString)
            .build();
        return MongoClients.create(mongoClientSettings);
    }
}