본문 바로가기
개발/java,spring,springboot

spring boot query dsl (data source 여러개 설정)

by 개발자종혁 2021. 4. 7.
728x90

전체 코드

jonghyeok34/spring-querydsl-multiple-datasource (github.com)

 

jonghyeok34/spring-querydsl-multiple-datasource

Contribute to jonghyeok34/spring-querydsl-multiple-datasource development by creating an account on GitHub.

github.com

 

설정

docker를 사용해 db 올리기

jonghyeok-dev.tistory.com/44

 

Spring boot jpa datasource 여러 개 설정(multiple datasource)

설정 mysql build하기 docker로 mysql build 하기 (tistory.com) docker로 mysql build 하기 도커 다운로드 도커다운로드 도커 build Dockerfile FROM mysql:8.0.21 # 인코딩 ENV LC_ALL=C.UTF-8 ENV character-se..

jonghyeok-dev.tistory.com

 

build.gradle

buildscript {
    ext {
        queryDslVersion = "4.3.0"
    }
}
plugins {
    id 'org.springframework.boot' version '2.3.9.RELEASE'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"

    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'


configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    querydsl.extendsFrom compileClasspath
}

repositories {
    mavenCentral()
}

dependencies {

    // web
    implementation 'org.springframework.boot:spring-boot-starter-web'

    // jpa
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

    // query dsl
    implementation 'com.querydsl:querydsl-jpa'
    implementation 'com.querydsl:querydsl-apt'
    annotationProcessor 'com.querydsl:querydsl-apt'

    runtimeOnly 'mysql:mysql-connector-java'

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

test {
    useJUnitPlatform()
}

def querydslDir = "$buildDir/generated/querydsl"

querydsl {
    jpa = true
    querydslSourcesDir = querydslDir
    library = "com.querydsl:querydsl-apt"
}
sourceSets {
    main.java.srcDir querydslDir
}
compileQuerydsl {
    options.annotationProcessorPath = configurations.querydsl
}

 

application.yaml

server:
  port: 9090

spring:

  jpa:
    hibernate:
        ddl-auto: create  # create or update
        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:3307/SCHEMA_NAME?serverTimezone=UTC&characterEncoding=UTF-8
        username: root
        password: password

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

 

PrimaryDataSourceConfig.java

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "primaryEntityManagerFactory",
        transactionManagerRef = "primaryTransactionManager",
        basePackages = { "com.example.demo.primary.repository" }
)
public class PrimaryDataSourceConfig {

    @Primary
    @Bean
    @ConfigurationProperties("primary.datasource")
    public DataSourceProperties primaryDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Primary
    @Bean
    @ConfigurationProperties("primary.datasource.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.demo.primary.model")
                        .persistenceUnit("primaryEntityManager")
                        .build();
    }

    @Primary
    @Bean
    public PlatformTransactionManager primaryTransactionManager(@Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

 

SecondaryDataSourceConfig

package com.example.demo.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

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;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "secondaryEntityManagerFactory",
        transactionManagerRef = "secondaryTransactionManager",
        basePackages = { "com.example.demo.secondary.repository" }
)
public class SecondaryDataSourceConfig {

    @Bean
    @ConfigurationProperties("secondary.datasource")
    public DataSourceProperties secondaryDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.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.demo.secondary.model")
                        .persistenceUnit("secondaryEntityManager")
                        .build();
    }

    @Bean
    public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

 

QuerydslConfig.java

package com.example.demo.config;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import com.querydsl.jpa.impl.JPAQueryFactory;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuerydslConfig {
    @PersistenceContext(unitName = "primaryEntityManager")
    EntityManager entityManager1;

    @PersistenceContext(unitName = "secondaryEntityManager")
    EntityManager entityManager2;

    @Bean
    public JPAQueryFactory primaryQueryFactory() {
        return new JPAQueryFactory(entityManager1);
    }

    @Bean(name="secondaryQueryFactory")
    public JPAQueryFactory secondaryQueryFactory() {
        return new JPAQueryFactory(entityManager2);
    }
}

 

PrimaryQuerydslRepositorySupport.java

package com.example.demo.config.querydsl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.springframework.stereotype.Repository;

@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);
    }

}

 

SecondaryQuerydslRepositorySupport.java

package com.example.demo.config.querydsl;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.springframework.stereotype.Repository;

@Repository
public abstract class SecondaryQuerydslRepositorySupport extends QuerydslRepositorySupport {

    public SecondaryQuerydslRepositorySupport(Class<?> domainClass) {
        super(domainClass);
    }

    @Override
    @PersistenceContext(unitName = "secondaryEntityManager")
    public void setEntityManager(EntityManager entityManager) {
        super.setEntityManager(entityManager);
    }

}

 

 

구현

 

TestEntityQueryDslRepository.java

package com.example.demo.primary.repository;

import java.util.List;

import com.example.demo.config.querydsl.PrimaryQuerydslRepositorySupport;
import com.example.demo.primary.model.QTestEntity;
import com.example.demo.primary.model.TestEntity;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;

import org.springframework.stereotype.Repository;

@Repository
public class TestEntityQueryDslRepository extends PrimaryQuerydslRepositorySupport {

    // QuerydslConfig 생성한 빈 이름과 
    private final JPAQueryFactory primaryQueryFactory;

    public TestEntityQueryDslRepository( JPAQueryFactory primaryQueryFactory) {
       super(TestEntity.class);
       this.primaryQueryFactory = primaryQueryFactory;
    }

    public List<TestEntity> findAll(){
        QTestEntity testEntity = QTestEntity.testEntity;

        return primaryQueryFactory.select(Projections.fields(
            TestEntity.class, 
            testEntity.id,
            testEntity.column
            ))
            .from(testEntity).fetch();
    }

}

 

SecondTestEntityQueryDslRepository.java

package com.example.demo.secondary.repository;

import java.util.List;

import com.example.demo.config.querydsl.SecondaryQuerydslRepositorySupport;
import com.example.demo.secondary.model.QSecondTestEntity;
import com.example.demo.secondary.model.SecondTestEntity;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

@Repository
public class SecondTestEntityQueryDslRepository extends SecondaryQuerydslRepositorySupport {

    private final JPAQueryFactory factory;

    public SecondTestEntityQueryDslRepository(@Qualifier("secondaryQueryFactory") JPAQueryFactory factory) {
        super(SecondTestEntity.class);
        this.factory = factory;
    }

    public List<SecondTestEntity> findAll(){
        QSecondTestEntity entity = QSecondTestEntity.secondTestEntity;

        return factory.select(Projections.fields(
            SecondTestEntity.class, 
            entity.id,
            entity.column
            ))
            .from(entity).fetch();
    }

}

 

PrimaryService.java

import com.example.demo.primary.model.TestEntity;
import com.example.demo.primary.repository.TestEntityQueryDslRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PrimaryService {

    @Autowired
    private TestEntityQueryDslRepository repo;

    public PrimaryService(TestEntityQueryDslRepository repo){
        this.repo = repo;
    }

    public List<TestEntity> findAll(){
        return repo.findAll();
    }
}

 

SecondaryService.java

package com.example.demo.secondary;

import java.util.List;

import com.example.demo.secondary.model.SecondTestEntity;
import com.example.demo.secondary.repository.SecondTestEntityQueryDslRepository;

import org.springframework.stereotype.Service;

@Service
public class SecondaryService {

    private final SecondTestEntityQueryDslRepository repo;
    public SecondaryService(SecondTestEntityQueryDslRepository repo){
        this.repo = repo;
    }
    public List<SecondTestEntity> findAll(){
        return repo.findAll();
    }
}

 

MainController.java

package com.example.demo;

import com.example.demo.primary.PrimaryService;
import com.example.demo.secondary.SecondaryService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MainController {
    @Autowired
    private PrimaryService primaryService;
    @Autowired
    private SecondaryService secondaryService;


    @GetMapping("/fetch")
    public String fetch(){
        secondaryService.findAll();
        primaryService.findAll();
        return "fetch";
    }
}

 

728x90

댓글