Spring Batch - классифицируйте предметы по разным типам - PullRequest
0 голосов
/ 18 июня 2020

Взяв ссылку из ссылки: Spring Batch - Как читать из одной таблицы и записывать данные в две разные таблицы , на самом деле я хотел классифицировать элементы по разным типам элементов в целом.

Здесь я хочу разделить элементы на Customer таблицу и NewCustomer таблицу в зависимости от различных условий, чтобы я мог сохранить данные в двух разных таблицах.

Вот мой пример кода, который, похоже, не работает.

ClassifierCompositeItemApplication. java

@EnableBatchProcessing
@SpringBootApplication
public class ClassifierCompositeItemApplication {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Value("classpath:input/customer.csv")
    private Resource inputResource;

    public ClassifierCompositeItemApplication(JobBuilderFactory jobs, StepBuilderFactory steps) {
        this.jobBuilderFactory = jobs;
        this.stepBuilderFactory = steps;
    }

    @Bean
    @StepScope
    public FlatFileItemReader<Customer> classifierCompositeWriterItemReader() {
        return new FlatFileItemReaderBuilder<Customer>()
                .name("customerFileReader")
                .resource(inputResource)
                .delimited()
                .names(new String[] { "firstName", "middleInitial", "lastName", "address", "city", "state", "zip" })
                .targetType(Customer.class)
                .build();
    }

    @Bean
    public ClassifierCompositeItemWriter<Customer> compositeItemWriter() throws IOException {
        final Classifier<Customer, ItemWriter<? super Customer>> classifier = new CustomerClassifier(
                this.customer1(), this.customer2());

        return new ClassifierCompositeItemWriterBuilder<Customer>()
                .classifier(classifier)
                .build();
    }

    @Bean
    @StepScope
    public ItemStreamWriter<Customer> customer1() throws IOException {
        System.out.println("Customer #1");
        return new ItemStreamWriter<Customer>() {

            @Override
            public void open(ExecutionContext executionContext) throws ItemStreamException {

            }

            @Override
            public void update(ExecutionContext executionContext) throws ItemStreamException {

            }

            @Override
            public void close() throws ItemStreamException {

            }

            @Override
            public void write(List<? extends Customer> items) throws Exception {
                for (Customer customer : items) {
                    System.out.println(customer);
                }
            }
        };
    }

    @Bean
    public ItemStreamWriter<Customer> customer2() {
        System.out.println("Customer #2");
        return new ItemStreamWriter<Customer>() {

            @Override
            public void open(ExecutionContext executionContext) throws ItemStreamException {

            }

            @Override
            public void update(ExecutionContext executionContext) throws ItemStreamException {

            }

            @Override
            public void close() throws ItemStreamException {

            }

            @Override
            public void write(List<? extends Customer> items) throws Exception {
                for (Customer customer : items) {
                    System.out.println(customer);
                }
            }
        };
    }


    @Bean
    public Step classifierCompositeWriterStep() throws IOException {
        return this.stepBuilderFactory.get("compositeWriterStep")
                .<Customer, Customer>chunk(10)
                .reader(this.classifierCompositeWriterItemReader())
                .writer(this.compositeItemWriter())
                .stream(this.customer1())
                .stream(this.customer2())
                .build();

    }


    @Bean
    public Job classifierCompositeWriterJob() throws IOException {
        return this.jobBuilderFactory.get("compositeWriterJob")
                .start(this.classifierCompositeWriterStep())
                .build();
    }


    public static void main(String[] args) {
        SpringApplication.run(ClassifierCompositeItemApplication.class, args);
    }
}

CustomerClassifier. java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CustomerClassifier implements Classifier<Customer, ItemWriter<? super Customer>> {
    private static final long serialVersionUID = 1L;

    private ItemWriter<Customer> fileItemWriter;
    private ItemWriter<Customer> jdbcItemWriter;

    @Override
    public ItemWriter<? super Customer> classify(Customer customer) {
        if (customer.getState().matches("^[A-M].*")) {
            return fileItemWriter;
        } else {
            return jdbcItemWriter;
        }
    }
}

Customer. java

public class Customer implements Serializable {

    private String firstName;
    private String middleInitial;
    private String lastName;
    ....
    ....
    //
}

Новый клиент. java

public class NewCustomer implements Serializable {

    private String firstName;
    private String middleInitial;
    private String lastName;
    ....
    ....
    // All different fields
}

1 Ответ

0 голосов
/ 22 июня 2020

Из Reader, скажем, у читателя есть 10 полей, 5 полей будут go в таблице клиентов, а другие 5 полей будут go в таблице NewCustomer

В этом случае вы не Не нужен этот объект NewCustomer и этот классификатор. Для составного модуля записи достаточно двух модулей записи jdb c: один вставляет в customer field1, .. field5, а другой вставляет в new_customer field6, ... field 10. Поля с 1 по 10 берутся из Customer объект, возвращенный вашим читателем.

Отлично, спасибо, не могли бы вы показать код?

Сначала создайте двух писателей jdb c, каждый должен вставить в заданную таблицу:

@Bean
public JdbcBatchItemWriter<Customer> writer1(DataSource dataSource) {
    return new JdbcBatchItemWriterBuilder<Customer>()
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
            .sql("INSERT INTO CUSTOMER (field1, field2) VALUES (:field1, :field2)")
            .dataSource(dataSource)
            .build();
}

@Bean
public JdbcBatchItemWriter<Customer> writer2(DataSource dataSource) {
    return new JdbcBatchItemWriterBuilder<Customer>()
            .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
            .sql("INSERT INTO NEW_CUSTOMER (field3, field4) VALUES (:field3, :field4)")
            .dataSource(dataSource)
            .build();
}

Затем скомпоновать их в составной писатель:

@Bean
public CompositeItemWriter<Customer> compositeItemWriter(DataSource dataSource) {
    return new CompositeItemWriterBuilder<Customer>()
            .delegates(Arrays.asList(writer1(dataSource), writer2(dataSource)))
            .build();
}

Очевидно, что Customer объект, возвращаемый вашим читателем, должен иметь field1 .. field4.

...