ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20. ItemWriter (DB)
    BackEnd/Spring Batch 2021. 12. 31. 18:30
    반응형

    JdbcBatchItemWriter

    Architecture

      JdbcCursorItemReader 설정과 마찬가지로 datasource를 지정하고, sql 속성에 실행할 쿼리를 설정합니다. JDBC의 Batch 기능을 사용하여 bulk insert/update/delete 방식으로 처리합니다. 단건 처리가 아닌 일괄처리이기 때문에 성능에 이점을 가집니다.

     

    API

    package io.springbatch.springbatchlecture;
    
    import lombok.RequiredArgsConstructor;
    import org.springframework.batch.core.*;
    import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
    import org.springframework.batch.core.launch.support.RunIdIncrementer;
    import org.springframework.batch.item.database.*;
    import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
    import org.springframework.batch.item.database.support.MySqlPagingQueryProvider;
    import org.springframework.batch.item.json.JacksonJsonObjectMarshaller;
    import org.springframework.batch.item.json.JsonFileItemWriter;
    import org.springframework.batch.item.json.builder.JsonFileItemWriterBuilder;
    import org.springframework.batch.item.xml.StaxEventItemWriter;
    import org.springframework.batch.item.xml.builder.StaxEventItemWriterBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.oxm.xstream.XStreamMarshaller;
    
    import javax.sql.DataSource;
    import java.util.*;
    
    @RequiredArgsConstructor
    @Configuration
    public class JdbcBatchConfiguration {
    
        private final JobBuilderFactory jobBuilderFactory;
        private final StepBuilderFactory stepBuilderFactory;
        private final DataSource dataSource;
    
        @Bean
        public Job job() throws Exception {
            return jobBuilderFactory.get("batchJob")
                    .incrementer(new RunIdIncrementer())
                    .start(step1())
                    .build();
        }
    
        @Bean
        public Step step1() throws Exception {
            return stepBuilderFactory.get("step1")
                    .<Customer, Customer>chunk(10)
                    .reader(customItemReader())
                    .writer(customItemWriter())
                    .build();
        }
    
        @Bean
        public JdbcPagingItemReader<Customer> customItemReader() {
    
            JdbcPagingItemReader<Customer> reader = new JdbcPagingItemReader<>();
    
            reader.setDataSource(this.dataSource);
            reader.setFetchSize(10);
            reader.setRowMapper(new CustomerRowMapper());
    
            MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
            queryProvider.setSelectClause("id, firstName, lastName, birthdate");
            queryProvider.setFromClause("from customer");
            queryProvider.setWhereClause("where firstname like :firstname");
    
            Map<String, Order> sortKeys = new HashMap<>(1);
    
            sortKeys.put("id", Order.ASCENDING);
            queryProvider.setSortKeys(sortKeys);
            reader.setQueryProvider(queryProvider);
    
            HashMap<String, Object> parameters = new HashMap<>();
            parameters.put("firstname", "A%");
    
            reader.setParameterValues(parameters);
    
            return reader;
        }
    
        @Bean
        public JdbcBatchItemWriter<Customer> customItemWriter() {
            return new JdbcBatchItemWriterBuilder<Customer>()
                    .dataSource(dataSource)
                    .sql("insert into customer2 values (:id, :firstName, :lastName, :birthdate)")
    //                .beanMapped()
                    .columnMapped()
                    .build();
        }
    
        /*@Bean
        public JdbcBatchItemWriter<Customer> customItemWriter() {
            JdbcBatchItemWriter<Customer> itemWriter = new JdbcBatchItemWriter<>();
            itemWriter.setDataSource(this.dataSource);
            itemWriter.setSql("insert into customer2 values (:id, :firstName, :lastName, :birthdate)");
            itemWriter.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider());
            itemWriter.afterPropertiesSet();
            return itemWriter;
        }*/
    }

     

    JpaItemWriter

    Architecture

      JPA Entity 기반으로 데이터를 처리하며 EntityManagerFactory를 주입받아 사용합니다. Entity를 하나씩 chunk 크기 만큼 insert 혹은 merge한 다음 flush 합니다. ItemReader나 ItemProcessor로부터 아이템을 전달 받을 때는 Entity 클래스 타입으로 받아야 합니다.

     

    API

    package io.springbatch.springbatchlecture;
    
    import lombok.RequiredArgsConstructor;
    import org.springframework.batch.core.*;
    import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
    import org.springframework.batch.core.launch.support.RunIdIncrementer;
    import org.springframework.batch.item.ItemProcessor;
    import org.springframework.batch.item.database.*;
    import org.springframework.batch.item.database.builder.JdbcBatchItemWriterBuilder;
    import org.springframework.batch.item.database.builder.JpaItemWriterBuilder;
    import org.springframework.batch.item.database.support.MySqlPagingQueryProvider;
    import org.springframework.batch.item.json.JacksonJsonObjectMarshaller;
    import org.springframework.batch.item.json.JsonFileItemWriter;
    import org.springframework.batch.item.json.builder.JsonFileItemWriterBuilder;
    import org.springframework.batch.item.xml.StaxEventItemWriter;
    import org.springframework.batch.item.xml.builder.StaxEventItemWriterBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.FileSystemResource;
    import org.springframework.oxm.xstream.XStreamMarshaller;
    
    import javax.persistence.EntityManagerFactory;
    import javax.sql.DataSource;
    import java.util.*;
    
    @RequiredArgsConstructor
    @Configuration
    public class JpaConfiguration {
    
        private final JobBuilderFactory jobBuilderFactory;
        private final StepBuilderFactory stepBuilderFactory;
        private final DataSource dataSource;
        private final EntityManagerFactory entityManagerFactory;
    
        @Bean
        public Job job() throws Exception {
            return jobBuilderFactory.get("batchJob")
                    .incrementer(new RunIdIncrementer())
                    .start(step1())
                    .build();
        }
    
        @Bean
        public Step step1() throws Exception {
            return stepBuilderFactory.get("step1")
                    .<Customer, Customer2>chunk(10)
                    .reader(customItemReader())
                    .processor(customItemProcess())
                    .writer(customItemWriter())
                    .build();
        }
    
        @Bean
        public JpaItemWriter<Customer2> customItemWriter() {
            return new JpaItemWriterBuilder<Customer2>()
                    .entityManagerFactory(entityManagerFactory)
                    .usePersist(true)
                    .build();
        }
    
        @Bean
        public ItemProcessor<? super Customer, ? extends Customer2> customItemProcess() {
            return new CustomItemProcess();
        }
    
        @Bean
        public JdbcPagingItemReader<Customer> customItemReader() {
    
            JdbcPagingItemReader<Customer> reader = new JdbcPagingItemReader<>();
    
            reader.setDataSource(this.dataSource);
            reader.setFetchSize(10);
            reader.setRowMapper(new CustomerRowMapper());
    
            MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();
            queryProvider.setSelectClause("id, firstName, lastName, birthdate");
            queryProvider.setFromClause("from customer");
            queryProvider.setWhereClause("where firstname like :firstname");
    
            Map<String, Order> sortKeys = new HashMap<>(1);
    
            sortKeys.put("id", Order.ASCENDING);
            queryProvider.setSortKeys(sortKeys);
            reader.setQueryProvider(queryProvider);
    
            HashMap<String, Object> parameters = new HashMap<>();
            parameters.put("firstname", "C%");
    
            reader.setParameterValues(parameters);
    
            return reader;
        }
    
    }

    [전체 소스 코드]

     

    [참고자료]

    인프런-스프링 배치 - Spring Boot 기반으로 개발하는 Spring Batch

    반응형

    'BackEnd > Spring Batch' 카테고리의 다른 글

    22. ItemProcessor  (0) 2022.01.04
    21. ItemWriterAdapter  (0) 2021.12.31
    19. ItemWriter (Json)  (0) 2021.12.31
    18. ItemWriter (XML)  (0) 2021.12.31
    17. ItemWriter (File)  (0) 2021.12.31

    댓글

Designed by Tistory.