Как разложить сущность в несколько таблиц с использованием spring-batch?

136
27 марта 2021, 13:20

Использую spring-batch чтобы разложить сущность по табличкам. Возник вопрос в написании writer'а

Сущность, для которой все работает. Могу положить из источника в таблицу 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;
    }

создается writer-бин, в котором формируется запрос как именно раскладывать сущность User по таблице User_export. C Этим все ок.

2) Теперь у сущности User добавляется поле, состоящее из списка элементов

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

Задача заключается в том, чтобы все поля User сложить в одну таблицу, а все devices связать внешним ключом с основной таблицей и записать все элементы в другую таблицу Device_export в несколько строк: Как решаю:

Собственно последовательность вызовов определяю так

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

reader->processor->writer

Читаю все записи из таблицы(откуда экспортирую) формируя объект User(один объект)

@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 в одну таблицу, а все devices - в другую

Я пробовал использовать 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;
    }

Но, имея такой writer, не понятно, а как тогда формировать входные данные для writer'ов, как сформировать отдельно список одних объектов Device, отдельно объект User.

    @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);
                // Не понятно что делать дальше
            }
        };
    }

Хотелось бы понять как правильно делать хотя бы на словах верхнеуровнево.

READ ALSO
Получить классы у которых конечное название одинаково

Получить классы у которых конечное название одинаково

Есть классы, например add_pdd-value, bdd_ogg-value, fff_ooo-value И таких классов штук 15Все заканчиваются на value

109
Помогите разобраться в выводе

Помогите разобраться в выводе

Дорогие программисты,есть маленький кусок кода,который я,к сожалению,не понял,а именно : почему на выходе получается function, в коде нет метода...

122
Как сохранить таблицу html

Как сохранить таблицу html

Сделал таблицу в html (Имя,код паспорта,номер телефона, сумма, "не погашено/погашено") Суть такова что надо чтоб при нажатие на имя вылезало окошко,...

190