Reputation: 1395
I user spring-batch to locate entity by tables. Question is about ItemWriter or, may be, about ItemProcessor.
For this entity everything okey. I can read entity from source and save it table User_export
@Getter @Setter
class User{
String objectId;
String rev;
String value;
String type;
}
And I had this 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) Than, I added field in my entity User. This field is list and I need to save this field in other table - Device_Export.
@Getter @Setter
class User{
String objectId;
String rev;
String value;
String type;
List<String> devices;
}
I have two tables User_export and Device_export. Device_export has foreign key to User_export and relation is many devices to one user. I need to map my user-entity by tables. So, my solution is:
@Bean
public Step exportStep1() {
return stepBuilderFactory.get("step1").<InputUser, List<OutputUser>>chunk(1)
.reader(reader())
.processor(processor())
.writer(writer())
.build();
}
reader->processor->writer
Reader (read entity from source talbe) - this is okey.
@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;
}
After processing, I have User entity with filled list of devices. I need to map it to tables:
I used 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;
}
But with ItemWriter like this, I can just write only one record in devices table. How to write list of devices(records) in Device_export?
My approximately processor like this:
@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);
// Не понятно что делать дальше
}
};
}
Upvotes: 4
Views: 2951
Reputation: 31720
The JdbcBatchItemWriter
won't help. You need to write the code to save a user with its devices
and wrap that code is a custom Spring Batch writer. Otherwise use an ORM to map your entities to tables and use the JpaItemWriter
or HibernateItemWriter
.
A similar question here: Read one record/item and write multiple records/items using spring batch
Upvotes: 1