Как создать Spring-Batch ItemWriter для сущности с полем ArrayList? - PullRequest
3 голосов
/ 11 июля 2019

Я использую Spring-Batch для определения сущности по таблицам.Вопрос о ItemWriter или, может быть, об ItemProcessor.

Для этой сущности все в порядке.Я могу прочитать сущность из источника и сохранить ее в таблице User_export

@Getter @Setter
class User{
    String objectId;
    String rev;
    String value;
    String type;
}

И у меня было это ItemWriter:

    @Bean
    @StepScope
    public ItemWriter<UserExport> writer() {
        JdbcBatchItemWriter<UserExport> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(dataSource);

        String sql = "insert into User_export(objectId, REV, Value, Type)" +
                "values (:objectId, :rev, :value, :type)";
        writer.setSql(sql);

        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.afterPropertiesSet();
        return writer;
    }

2) Чем я добавил полев моей сущности пользователя.Это поле списка, и мне нужно сохранить это поле в другой таблице - Device_Export.

@Getter @Setter
class User{
    String objectId;
    String rev;
    String value;
    String type;
    List<String> devices;
}

У меня есть две таблицы User_export и Device_export.Device_export имеет внешний ключ к User_export и имеет отношение много устройств к одному пользователю.Мне нужно отобразить мою пользовательскую сущность по таблицам.Итак, мое решение:

     @Bean
    public Step exportStep1() {
        return stepBuilderFactory.get("step1").<InputUser, List<OutputUser>>chunk(1)
                .reader(reader())
                .processor(processor())
                .writer(writer())
                .build();
    }

читатель-> процессор-> писатель

читатель (чтение сущности из источника talbe) - это хорошо.

@Bean
public JdbcCursorItemReader<User> reader() {
    JdbcCursorItemReader<InputUser> reader = new JdbcCursorItemReader<>();
    String sql = "select * from User_Table";
    reader.setSql(sql);
    reader.setDataSource(dataSource);
    reader.setName("User_Table");
    reader.setRowMapper(new BeanPropertyRowMapper<>(User.class));
    return reader;
}

После обработки у меня появляется сущность User с заполненным списком устройств.Мне нужно сопоставить его с таблицами:

Я использовал ComposeWriter:

@Bean
    @StepScope
    @DependsOn({"userWriter", "deviceWriter"})
    public CompositeItemWriter composeWriter() {
        CompositeItemWriter writer = new CompositeItemWriter();

        ItemWriter<UserExport> userWriter = userWriter();
        ItemWriter<DeviceExport> deviceWriter = deviceWriter();
        List<ItemWriter> writers = new ArrayList<>();
        writers.add(userWriter);
        writers.add(deviceWriter);

        writer.setDelegates(writers);
        return writer;
    }


    @Bean
    @StepScope
    public ItemWriter<UserExport> userWriter() {
        JdbcBatchItemWriter<UserExport> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(dataSource);

        String sql = "insert into User_Export (objectId, REV, Value, Type)" 
                "values (:objectId, :rev, :value, :type)";
        writer.setSql(sql);

        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.afterPropertiesSet();
        return writer;
    }

    @Bean
    @StepScope
    public ItemWriter<DeviceExport> deviceWriter() {
        JdbcBatchItemWriter<DeviceExport> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(dataSource);

        String sql = "insert into Device_Export (PR_KEY, objectId, device) values (:prKey, :objectId, :device)";
        writer.setSql(sql);

        writer.setItemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>());
        writer.afterPropertiesSet();
        return writer;
    }

Но с таким ItemWriter я могу просто записать только одну запись в таблицу устройств.Как записать список устройств (записей) в Device_export?

Мой примерно такой процессор, как этот:

    @Bean
    public ItemProcessor<User, List<OutputUser>> processor() {
        return new ItemProcessor<User, List<OutputUser>>() {
            @Override
            public List<OutputUser> process(OutputUser item) throws Exception {
                OutputUser outputUser = mapToUser(item);
                List<OutputDevice> outputDevices = mapToDevices(item);
                // Не понятно что делать дальше
            }
        };
    }

1 Ответ

1 голос
/ 12 июля 2019

JdbcBatchItemWriter не поможет.Вам нужно написать код, чтобы сохранить пользователя с его devices, и обернуть этот код в программу, созданную пользователем Spring Batch.В противном случае используйте ORM для сопоставления ваших сущностей с таблицами и используйте JpaItemWriter или HibernateItemWriter.

Аналогичный вопрос здесь: Чтение одной записи / элемента и запись нескольких записей / элементов с использованием весенней партии

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...