SpringBoot, JPA, QueryDsl, Mysql, Gradle 환경에서 2개 이상의 DB를 이용하는 샘플소스 입니다.
하나의 DB를 사용할 때는 application.yml 파일에 DB에 대한 정보만 설정해 주면 자동으로 Entity 와 Repository를 스캔해서 세팅을 해줍니다. 그러나, 다중 DB를 사용하기 위해서는 JPA에서 자동으로 설정해 주던 것들을 수동으로 설정해야 합니다.
다중 DB를 사용하기 위해서는 아래 3개를 설정해야 합니다.
- Datasource 설정
- EntityManager Bean 등록
- QueryFactory Bean 등록
1. 샘플 프로젝트 패키지 구조
2. JPA 프로젝트 설정파일 (build.gradle, application.yml)
2.1. build.gradle 파일
buildscript {
ext {
queryDslVersion = "5.0.0"
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.5'
id 'io.spring.dependency-management' version '1.1.4'
// querydsl 플러그인 추가
id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '11'
}
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // JPA
implementation 'com.querydsl:querydsl-jpa' // QueryDSL
implementation 'com.querydsl:querydsl-apt' // QueryDSL
implementation 'org.springframework.boot:spring-boot-starter-web' // Web
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
//querydsl 추가 Start
//def querydslDir = 'src/main/generated'
def querydslDir = "$buildDir/generated/querydsl"
querydsl {
library = "com.querydsl:querydsl-apt"
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets {
main {
java {
srcDirs = ['src/main/java', querydslDir]
}
}
}
compileQuerydsl{
options.annotationProcessorPath = configurations.querydsl
}
configurations {
querydsl.extendsFrom compileClasspath
}
//querydsl 추가 End
2.2. application.yml 파일
spring:
jpa:
hibernate:
ddl-auto: none # create or update or none
use-new-id-generator-mappings: false
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
properties:
hibernate.dialect: org.hibernate.dialect.MySQL5InnoDBDialect
primary:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/{첫번째 DB}
username: {아이디}
password: {비밀번호}
secondary:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/{두번째 DB}
username: {아이디}
password: {비밀번호}
3. Datasource 설정
예를 들어 2개의 Datasource 를 생성할 경우, 첫 번째 Datasource는 primaryDataSource, 두 번째 Datasource는 secondaryDataSource라고 하겠습니다.
3.1. 첫 번째 DB (primaryDataSource) 설정 Class - PrimaryDataSourceConfig.java
package com.example.multidb.config;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
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 org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "primaryEntityManagerFactory", // EntityManager 이름
transactionManagerRef = "primaryTransactionManager", // TransactionManager 이름
basePackages = { "com.example.multidb.primary.repository" } // 첫번째 DB repository 패키지 경로
)
public class PrimaryDataSourceConfig {
@Primary
@Bean
@ConfigurationProperties("spring.primary.datasource") // application.yml 에서 첫번째 DB관련 설정
public DataSourceProperties primaryDataSourceProperties() {
return new DataSourceProperties();
}
@Primary
@Bean
@ConfigurationProperties("spring.primary.datasource.configuration") // DB와 관련된 설정값들의 접두사에 .configuration을 붙임.
public DataSource primaryDataSource(@Qualifier("primaryDataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("primaryDataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.example.multidb.primary.entity") // 첫번째 DB entity 패키지 경로
.persistenceUnit("primaryEntityManager")
.build();
}
@Primary
@Bean
public PlatformTransactionManager primaryTransactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
4개의 Bean을 등록하는데, 첫 번째 DB 설정 클래스의 Bean에는 @Primary를 붙여둡니다.
3.2. 두 번째 DB (secondaryDataSource) 설정 Class - SecondaryDataSourceConfig.java
package com.example.multidb.config;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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 org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "secondaryEntityManagerFactory", // EntityManager 이름
transactionManagerRef = "secondaryTransactionManager", // TransactionManager 이름
basePackages = { "com.example.multidb.secondary.repository" } // 두번째 DB repository 패키지 경로
)
public class SecondaryDataSourceConfig {
@Bean
@ConfigurationProperties("spring.secondary.datasource") // application.yml 에서 두번재 DB관련 설정
public DataSourceProperties secondaryDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.datasource.configuration") // DB와 관련된 설정값들의 접두사에 .configuration을 붙임.
public DataSource secondaryDataSource(@Qualifier("secondaryDataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("secondaryDataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("com.example.multidb.secondary.entity") // 두번째 DB model(Entity) 패키지 경로
.persistenceUnit("secondaryEntityManager")
.build();
}
@Bean
public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
3.3. JPA, Querydsl 설정 Bean 등록 - QuerydslConfig.java
package com.example.multidb.config;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Configuration
public class QuerydslConfig {
// JPA 관련 설정(primary)
@PersistenceContext(unitName = "primaryEntityManager")
EntityManager entityManager1;
// JPA 관련 설정(secondary)
@PersistenceContext(unitName = "secondaryEntityManager")
EntityManager entityManager2;
// QueryDsl 관련설정(primary)
@Bean
public JPAQueryFactory primaryQueryFactory() {
return new JPAQueryFactory(entityManager1);
}
// QueryDsl 관련설정(secondary)
@Bean(name="secondaryQueryFactory")
public JPAQueryFactory secondaryQueryFactory() {
return new JPAQueryFactory(entityManager2);
}
}
EntityManager 와 JPAQueryFactory를 등록 하고, Bean이 필요한 곳에서 주입하여 사용합니다.
3.4. 첫 번재 DB Repository 설정 - PrimaryQuerydslRepositorySupport.java
package com.example.multidb.config.querydsl;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Repository
public abstract class PrimaryQuerydslRepositorySupport extends QuerydslRepositorySupport {
public PrimaryQuerydslRepositorySupport(Class<?> domainClass) {
super(domainClass);
}
@Override
@PersistenceContext(unitName = "primaryEntityManager")
public void setEntityManager(EntityManager entityManager) {
super.setEntityManager(entityManager);
}
}
3.5. 두 번째 DB Repository 설정 - SecondaryQuerydslRepositorySupport.java
package com.example.multidb.config.querydsl;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Configuration
public abstract class SecondaryQuerydslRepositorySupport extends QuerydslRepositorySupport {
public SecondaryQuerydslRepositorySupport(Class<?> domainClass) {
super(domainClass);
}
@Override
@PersistenceContext(unitName = "secondaryEntityManager")
public void setEntityManager(EntityManager entityManager) {
super.setEntityManager(entityManager);
}
}
"SpringBoot JPA + Querydsl 다중 Datasource 설정 2" 는 다중 Datasource 설정을 이용해서 2개 DB에 데이터를 저장 하고 조회하는 샘플입니다.
https://ksshim.tistory.com/135
SpringBoot JPA + Querydsl 다중 Datasource 설정 2
https://ksshim.tistory.com/134 SpringBoot JPA + Querydsl 다중 Datasource 설정 1 SpringBoot, JPA, QueryDsl, Mysql, Gradle 환경에서 2개 이상의 DB를 이용하는 샘플소스 입니다. 하나의 DB를 사용할 때는 application.yml 파일에 D
ksshim.tistory.com
[테스트 프로젝트 소스 다운받기]
https://github.com/ksshim0228/multidb.git
GitHub - ksshim0228/multidb
Contribute to ksshim0228/multidb development by creating an account on GitHub.
github.com
'SpringBoot' 카테고리의 다른 글
SpringBoot 외부 프로퍼티 적용하기(application.yml) (0) | 2023.12.06 |
---|---|
SpringBoot JPA + Querydsl 다중 Datasource 설정 2 (0) | 2023.11.29 |
SpringBoot - application.yml 중요정보 암호화(Jasypt) (0) | 2023.10.13 |
SpringBoot - Ajax로 보낸 JSON 데이터 서버에서 받기 (0) | 2022.12.16 |
SpringBoot - Form 데이터 주고 받기 (0) | 2022.12.16 |