티스토리 뷰

반응형

 

 

 

Spring



 

 

간혹 사이트들을 연계해야 할때,

그 중에서도 api 없는 사이트의 데이터를 사용해야할 때,

하나의 웹에서 여러 DB를 연결 시켜 사용해야 할 때가 있다.

 

간단하게 DB Link 로 해결하려 했으나 메인으로 쓰는 DB와  타 사이트 DB가 달라서 

복잡쿼리를 쓸때 제약이 쫌 발생해서  DB를 하나 더 연결하기로 했다.

 

 

 

SpringBoot 는 Database 연결을 자동으로 해주기 때문에

다중 DB를 연결하려면 설정부를 재작성해줘야 한다.

 

 

일단 db 연동 정보를 추가해준다.

 

spring:
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    jdbc-url: jdbc:mariadb://localhost:3306/jpa
    username: root
    password: ****

  second-datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    jdbc-url: jdbc:sqlserver://localhost:1433;database=sample
    username: local
    password: ****

 

기존 url 이라고 작성했던 부분을 jdbc-url 로 변경한다.

그리고 datasource 이름을 다르게 구분되도록 변경한다.

(driver-class-name은 작성안해도 url 보고 알아서 설정된다.)

 

 

 

 

이제 자동으로 연결되던 설정을 java코드로 재설정해준다.

이때 primary DB와 subDB 설정 2개를 해줘야 한다.

그리고 주 DB에 @primary 어노테이션을 지정해야 한다.

그렇지 않으면 bean 이 1개 이상이라고 에러가 발생한다.

 

그리고 @EnableJpaRepositories 로 Jpa 가 사용될 위치를 지정해준다.

 

@Configuration
@EnableJpaRepositories(
        basePackages = "com.sample.core.maria",
        entityManagerFactoryRef = "primaryEntityManager",
        transactionManagerRef = "primaryTransactionManager"
)
public class PrimaryConfig {

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

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean primaryEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(primaryDataSource());
        em.setPackagesToScan(new String[] {"com.sample.core.maria.test"});
        
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(true);
        vendorAdapter.setGenerateDdl(true);
        em.setJpaVendorAdapter(vendorAdapter);
        
        HashMap<String, Object> prop = new HashMap<>();
        prop.put("hibernate.dialect", "org.hibernate.dialect.MariaDBDialect");
        prop.put("hibernate.hbm2ddl.auto", "update");
        prop.put("hibernate.format_sql", true);
        em.setJpaPropertyMap(prop);
        
        return em;
    }

    @Bean
    @Primary
    public PlatformTransactionManager primaryTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(primaryEntityManager().getObject());
        return transactionManager;
    }
}

 

 

두번째 DB도 작성해주는데 @primary 없애는 것을 잊지 말자

@Configuration
@EnableJpaRepositories(
        basePackages = "com.sample.core.mssql",
        entityManagerFactoryRef = "secondEntityManager",
        transactionManagerRef = "secondTransactionManager"
)
public class SecondConfig {

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

    @Bean
    public LocalContainerEntityManagerFactoryBean secondEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(secondDataSource());
        em.setPackagesToScan(new String[] {"com.sample.core.mssql.test"});
        
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setShowSql(true);
        vendorAdapter.setGenerateDdl(true);
        em.setJpaVendorAdapter(vendorAdapter);
        
        HashMap<String, Object> prop = new HashMap<>();
        prop.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
        prop.put("hibernate.hbm2ddl.auto", "update");
        prop.put("hibernate.format_sql", true);
        em.setJpaPropertyMap(prop);
        
        return em;
    }

    @Bean
    public PlatformTransactionManager secondTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(secondEntityManager().getObject());
        return transactionManager;
    }
}

 

 

엔티티와 레파지토리를 간단하게 테스트용으로 작성해보았다.

 

@Entity
@Table(name = "board")
@Data
@NoArgsConstructor @AllArgsConstructor
public class BoardEntity {

    @Id @Column(name = "BOARD_ID")
    private String boardId;
    @Column(name = "BOARD_NAME")
    private String boardName;
}


@Repository
public interface BoardRepository extends JpaRepository<BoardEntity, String> {
}

 

@Entity
@Table(name = "post")
@Data
@NoArgsConstructor @AllArgsConstructor
public class PostEntity {

    @Id
    @Column(name = "POST_ID")
    private String postId;
    @Column(name="POST_NAME")
    private String postName;
}


@Repository
public interface PostRepository extends JpaRepository<PostEntity, String> {
}

 

 

 

엔티티 대로 각자의 DB에 테이블이 생성되고 값이 들어가는지 테스트 해보았다.

 

@SpringBootTest
public class MultiTest {

    @Autowired private PostService mssqlService;
    @Autowired private BoardService mariaService;


    @Test
    @Description("mssql test")
    void mssqlInsert() {
        PostEntity entity = new PostEntity("post999", "sub");
        mssqlService.insert(entity);
    }

    @Test
    @Description("maria test")
    void postgresqlInsert() {
        BoardEntity entity = new BoardEntity("board999", "primary");
        mariaService.insert(entity);
    }
}

 

 

 

 

mssql 에 생성

 

mariaDB 에 생성

 

 

 

잘 생성된 것을 확인했다.

 

 

그리고 jpa 설정에 jpa 관련 프로퍼티들도 직접 설정해줘야 올바르게 동작했다.

처음에 프로퍼티를 yml 에만 작성해놓고 테스트를 수행했더니

ddl-auto 를 update 으로 설정했음에도 테이블 없다는 오류가 발생했었다.

 

HashMap<String, Object> prop = new HashMap<>();
prop.put("hibernate.hbm2ddl.auto", "update");
em.setJpaPropertyMap(prop);

 

위와 같이 primary, second 설정에 jpa 관련 프로퍼티 설정도 해줘야 한다.

 

 

 

 



 

 

 

 

 

 

 

 

 

참고블로그

 

 

Spring Boot | JPA, 다중 데이터베이스 구성하기

구성환경 Spring Boot 2.7.0, MariaDB 10.5.13 기존에 하나의 데이터 소스를 통해 정상 작동하는 프로젝트에서 2개 이상의 데이터 소스를 사용하기 위해 작성된 내용입니다. 기본 스프링 부트 데이터베이

kitty-geno.tistory.com

 

SpringBoot JPA Multiple Databases 설정

다중 DB는 Spring boot 처럼 Auto Configuration되지 않음설정파일(application.yml 또는 application.properties) 값을 읽어와서 연동 할 DB 수 만큼 Datasource를 수동 설정해야함설정파일 대신 코드로 직접 설

velog.io

 

 

JPA, JDBC의 DB MultiDataSource 적용하기

JPA와 JDBC를 동시에 쓰고 싶다! JPA 그리고 JDBC 를 동시에 사용하는 방법은 그렇게 어렵지 않다. JPA 의존성 밑에 JDBC가 포함되어있어서 JDBC template를 이미 사용할 수 있는 구조로 되어있어서 의존성

sundries-in-myidea.tistory.com

 

반응형
댓글
반응형
최근에 올라온 글
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Total
Today
Yesterday