ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DB to DB 프로젝트 생성하기 (Spring Batch 5.0.x)
    SpringBatch 2024. 2. 5. 13:13

    https://miji-it.tistory.com/2

     

    Spring Batch의 개념과 개발 환경 세팅

    0. 개념 Batch Batch 작업이란, 데이터를 실시간으로 처리하는게 아니라, 일괄적으로 모아서 처리하는 작업을 의미한다. 하루동안 쌓인 데이터를 배치작업을 통해 특정 시간에 한 번에 처리하는 경

    miji-it.tistory.com

     

    https://miji-it.tistory.com/5

     

    Spring Batch project 만들기 전 DB 설정하기

    1. DB 연결 기존 구축 되어 있는 MariaDB service type을 NodePort로 수정 apiVersion: v1 kind: Service ... 생략 ... type: NodePort status: loadBalancer: {} NodePort 를 확인한다. root@edu7:~# k get svc -n minji NAME TYPE CLUSTER-IP EXTERNAL

    miji-it.tistory.com

    위의 과정을 모두 진행했다는 전제로 진행하는 프로젝트이다.



     

    뭔가 이상하게 안 된다 싶으면 application.yml에서 발생한 확률이 큰 듯하다.

    버전이 안 맞는 다는 이유로 뭐가 참 안 된다.

     

     

    resources/application.yml

    spring:
      profiles:
        active: mariadb
    
    ---
    
    spring:
      profiles:
        active: local
      datasource:
        hikari:
          jdbc-url: jdbc:h2:mem:db;MODE=MYSQL;
          username: sa
          password:
          driver-class-name: org.h2.Driver
      batch:
        job:
          enabled: true
    
    ---
    
    spring:
      profiles:
        active: mariadb
      datasource:
        hikari:
          jdbc-url: jdbc:mariadb://{{ip}}:{{port}}/my_database
          username: {{username}}
          password: {{password}}
          driver-class-name: org.mariadb.jdbc.Driver
      jpa:
        hibernate:
          ddl-auto: update
          naming:
            physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
        properties:
          hibernate:
            show_sql: true
            format_sql: true
      batch:
        job:
          enabled: true
          name: ${job.name:NONE}
        jdbc:
          initialize-schema: always

     

     

     

    build.gradle

    plugins {
        id 'java'
        id 'org.springframework.boot' version '3.0.5'
        id 'io.spring.dependency-management' version '1.1.0'
    }
    
    group = 'com.example'
    version = '0.0.1-SNAPSHOT'
    sourceCompatibility = '17'
    
    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        // Spring Batch
        implementation 'org.springframework.boot:spring-boot-starter-batch'
        // Spring Data JPA
        implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
        // h2 DB
        implementation 'com.h2database:h2'
        // 스프링 웹
        implementation 'org.springframework.boot:spring-boot-starter-web'
        // 롬복
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        // mariadb
        implementation 'org.mariadb.jdbc:mariadb-java-client:2.7.4'
    
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
    }
    
    tasks.named('test') {
        useJUnitPlatform()
    }

     

     

     

     

     

    entity/SourcePerson.java

    package com.example.playground.entity;
    
    import jakarta.persistence.*;
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    import java.util.Date;
    
    @Entity
    @Getter
    @Setter
    @ToString
    @Table(name = "SOURCE_PERSON")
    public class SourcePerson {
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private int id;
    	private String lastName;
    	private String firstName;
    	private Date birthDate;
    
    	public SourcePerson() {
    	}
    
    	public SourcePerson(int id, String firstName, String lastName, Date birthDate) {
    		this.id = id;
    		this.firstName = firstName;
    		this.lastName = lastName;
    		this.birthDate = birthDate;
    	}
    
    	@Override
    	public String toString() {
    		return "id:"+ id+"firstName: " + firstName + ", lastName: " + lastName+ ", birthDate: " + birthDate;
    	}
    
    }

     

     

     

     

     

    entity/TargetPerson.java

    package com.example.playground.entity;
    
    import jakarta.persistence.*;
    import lombok.Getter;
    import lombok.Setter;
    
    import java.util.Date;
    
    @Entity
    @Getter
    @Setter
    @Table(name = "TARGET_PERSON")
    public class TargetPerson {
    	@Id
    	@GeneratedValue(strategy = GenerationType.AUTO)
    	private int id;
    	private String lastName;
    	private String firstName;
    	private Date birthDate;
    
    	public TargetPerson() {
    	}
    
    	public TargetPerson(int id,String firstName, String lastName, Date birthDate) {
    		this.id = id;
    		this.firstName = firstName;
    		this.lastName = lastName;
    		this.birthDate = birthDate;
    	}
    
    	@Override
    	public String toString() {
    		return "id: " + id + "firstName: " + firstName + ", lastName: " + lastName+ ", birthDate: " + birthDate;
    	}
    
    }

     

     

     

     

    repository/SourcePersonRepository.java

    package com.example.playground.repository;
    
    import com.example.playground.entity.SourcePerson;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    public interface SourcePersonRepository extends JpaRepository<SourcePerson, Integer>{
    
    }

     

     

     

     

    repository/TargetPersonRepository.java

    package com.example.playground.repository;
    
    import com.example.playground.entity.TargetPerson;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    
    public interface TargetPersonRepository extends JpaRepository<TargetPerson, Integer> {
    }

     

     

     

     

    PersonItemProcessor.java

    package com.example.playground;
    
    import com.example.playground.entity.SourcePerson;
    import com.example.playground.entity.TargetPerson;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.batch.item.ItemProcessor;
    
    import java.util.Date;
    
    public class PersonItemProcessor implements ItemProcessor<SourcePerson, TargetPerson> {
    
    	private static final Logger log = LoggerFactory.getLogger(PersonItemProcessor.class);
    
    	@Override
    	public TargetPerson process(final SourcePerson sourcePerson) throws Exception {
    		final int id = sourcePerson.getId();
    		final String firstName = sourcePerson.getFirstName().toUpperCase();
    		final String lastName = sourcePerson.getLastName().toUpperCase();
    		final Date birthDate = sourcePerson.getBirthDate();
    
    		final TargetPerson transformedSourcePerson = new TargetPerson(firstName, lastName, birthDate);
    
    		log.info("Converting (" + sourcePerson + ") into (" + transformedSourcePerson + ")");
    
    		return transformedSourcePerson;
    	}
    
    }

     

     

     

     

    config/DBtoDBJobConfiguration.java

    package com.example.playground.config;
    
    import com.example.playground.PersonItemProcessor;
    import com.example.playground.entity.SourcePerson;
    import com.example.playground.entity.TargetPerson;
    import com.example.playground.repository.SourcePersonRepository;
    import com.example.playground.repository.TargetPersonRepository;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.Step;
    import org.springframework.batch.core.job.builder.JobBuilder;
    import org.springframework.batch.core.launch.support.RunIdIncrementer;
    import org.springframework.batch.core.repository.JobRepository;
    import org.springframework.batch.core.step.builder.StepBuilder;
    import org.springframework.batch.item.data.RepositoryItemReader;
    import org.springframework.batch.item.data.RepositoryItemWriter;
    import org.springframework.batch.item.data.builder.RepositoryItemReaderBuilder;
    import org.springframework.batch.item.data.builder.RepositoryItemWriterBuilder;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.domain.Sort;
    import org.springframework.transaction.PlatformTransactionManager;
    
    import javax.sql.DataSource;
    import java.util.Map;
    
    @Slf4j
    @Configuration
    public class DBtoDBJobConfiguration {
        @Autowired
        private SourcePersonRepository sourcePersonRepo;
    
        @Autowired
        private TargetPersonRepository targetPersonRepo;
    
        @Bean
        public Job db2dbJob(JobRepository jobRepository, Step step1) {
            return new JobBuilder("db2dbJob", jobRepository)
                    .incrementer(new RunIdIncrementer())
                    .flow(step1)
                    .end()
                    .build();
        }
        
        @Bean
        public Step step1(JobRepository jobRepository, RepositoryItemReader<SourcePerson> reader, RepositoryItemWriter<TargetPerson> writer, PlatformTransactionManager platformTransactionManager){
            return new StepBuilder("step1", jobRepository)
                    .<SourcePerson,TargetPerson>chunk(5, platformTransactionManager)
                    .reader(reader)
                    .processor(new PersonItemProcessor())
                    .writer(writer)
                    .build();
        }
    
        @Bean
        public RepositoryItemReader<SourcePerson> repositoryItemReader() {
            return new RepositoryItemReaderBuilder<SourcePerson>()
                    .name("repositoryItemReader")
                    .repository(sourcePersonRepo)
                    .methodName("findAll")
                    .pageSize(5)
                    .sorts(Map.of("id", Sort.Direction.ASC))
                    .build();
        }
    
        @Bean
        public PersonItemProcessor processor() {
            return new PersonItemProcessor();
        }
    
        @Bean
        public RepositoryItemWriter<TargetPerson> writer(DataSource dataSource) {
            return new RepositoryItemWriterBuilder<TargetPerson>()
                    .methodName("save")
                    .repository(targetPersonRepo)
                    .build();
        }
    
    
    }

     

Designed by Tistory.