Spring 批处理:处理多个实体并合并它们
Spring Batch: Working with several entities and merge them
我需要对存储在关系数据库中的数据进行非规范化。
彼此之间链接的表太多,不可能构建单个查询来获取所有数据。
这里是一个简化的情况:
+-------------+ +-------------+
| | 1 N | |
| Unitat +-----------> Authors |
| | | |
+-------------+ +-------------+
到目前为止,我已经构建了一个获取所有 Unitat
行的步骤:
@Bean
public ItemReader<Unitat> reader() {
String sql = "select * from unitat";
JdbcCursorItemReader<Unitat> jdbcCursorItemReader = new JdbcCursorItemReader<>();
jdbcCursorItemReader.setDataSource(this.dataSource);
jdbcCursorItemReader.setSql(sql);
jdbcCursorItemReader.setVerifyCursorPosition(false);
jdbcCursorItemReader.setRowMapper(new UnitatRowMapper());
return jdbcCursorItemReader;
}
RowMapper
是:
public class UnitatRowMapper implements RowMapper<Unitat> {
private static final String ID_COLUMN = "id";
//...
@Override
public Unitat mapRow(ResultSet resultSet, int numRow) throws SQLException {
Unitat unitat = new Unitat();
unitat.setId(resultSet.getString(ID_COLUMN));
//...
return unitat;
}
}
这是我的处理器。它仅用于将字段填充到 UnitatDenormalized
对象中:
@Component
public class UnitatMappingItemProcessor implements ItemProcessor<Unitat, UnitatDenormalized> {
@Override
public UnitatDenormalized process(Unitat unitat) throws Exception {
UnitatDenormalized denormalized = new UnitatDenormalized();
denormalized.setId(unitat.getId());
//denormalized.set...()
return denormalized;
}
}
这是我当前的步骤和作业配置:
@Bean
public Step step(
ItemReader<Unitat> mssqlItemReader,
UnitatMappingItemProcessor processor,
SolrItemWriter solrItemWriter
) {
return this.stepBuilderFactory
.get("unitat")
.<Unitat, UnitatDenormalized>chunk(100)
.reader(mssqlItemReader)
.processor(processor)
.writer(solrItemWriter)
.build();
}
@Bean
public Job job(Step step) {
Job job = this.jobBuilderFactory.get("job1")
.flow(step)
.end()
.build();
return job;
}
如何获取作者并将它们合并到之前获得的 unitat
?
我何时以及如何执行下一个代码?
// Here would I need to populate `authors`:
denormalized.addAutors(...);
denormalized.addAutors(...);
我希望我解释得很好...
可以使用driving query pattern。这个想法是在您的项目处理器中发出请求以丰富项目。
在您的例子中,查询将获取当前 unitat
项目的作者,并在返回之前将其设置在 denormalized
项目上。
我需要对存储在关系数据库中的数据进行非规范化。
彼此之间链接的表太多,不可能构建单个查询来获取所有数据。
这里是一个简化的情况:
+-------------+ +-------------+
| | 1 N | |
| Unitat +-----------> Authors |
| | | |
+-------------+ +-------------+
到目前为止,我已经构建了一个获取所有 Unitat
行的步骤:
@Bean
public ItemReader<Unitat> reader() {
String sql = "select * from unitat";
JdbcCursorItemReader<Unitat> jdbcCursorItemReader = new JdbcCursorItemReader<>();
jdbcCursorItemReader.setDataSource(this.dataSource);
jdbcCursorItemReader.setSql(sql);
jdbcCursorItemReader.setVerifyCursorPosition(false);
jdbcCursorItemReader.setRowMapper(new UnitatRowMapper());
return jdbcCursorItemReader;
}
RowMapper
是:
public class UnitatRowMapper implements RowMapper<Unitat> {
private static final String ID_COLUMN = "id";
//...
@Override
public Unitat mapRow(ResultSet resultSet, int numRow) throws SQLException {
Unitat unitat = new Unitat();
unitat.setId(resultSet.getString(ID_COLUMN));
//...
return unitat;
}
}
这是我的处理器。它仅用于将字段填充到 UnitatDenormalized
对象中:
@Component
public class UnitatMappingItemProcessor implements ItemProcessor<Unitat, UnitatDenormalized> {
@Override
public UnitatDenormalized process(Unitat unitat) throws Exception {
UnitatDenormalized denormalized = new UnitatDenormalized();
denormalized.setId(unitat.getId());
//denormalized.set...()
return denormalized;
}
}
这是我当前的步骤和作业配置:
@Bean
public Step step(
ItemReader<Unitat> mssqlItemReader,
UnitatMappingItemProcessor processor,
SolrItemWriter solrItemWriter
) {
return this.stepBuilderFactory
.get("unitat")
.<Unitat, UnitatDenormalized>chunk(100)
.reader(mssqlItemReader)
.processor(processor)
.writer(solrItemWriter)
.build();
}
@Bean
public Job job(Step step) {
Job job = this.jobBuilderFactory.get("job1")
.flow(step)
.end()
.build();
return job;
}
如何获取作者并将它们合并到之前获得的 unitat
?
我何时以及如何执行下一个代码?
// Here would I need to populate `authors`:
denormalized.addAutors(...);
denormalized.addAutors(...);
我希望我解释得很好...
可以使用driving query pattern。这个想法是在您的项目处理器中发出请求以丰富项目。
在您的例子中,查询将获取当前 unitat
项目的作者,并在返回之前将其设置在 denormalized
项目上。