我正在开发 Spring Boot Spring Batch 代码。从Oracle DB
中读取数据,并将所有数据加载到MongoDB (NOSQL DB)
中。 MongoDB
的建模是根据实现mongo关系/建模的标准方法以非标准化的方式开发的。
我有TableA
和TableB
表以及它们之间的联接表TableAB
,这是第三表。当我每次通过TableA
读取JdbcCursorItemReader<TableA>
表TableA
的每个 PK ID 时,我需要查询SubDivision
表以获取所有{ {1}}用于SubDivision
的PK,并填充SubDivision Data,将其设置为TableA模型。 TableA模型具有TableA
列表。
我看到的唯一方法是从SubDivisions
进行查询并将数据设置为TableAProcessor
的模型,这很容易实现,但是问题是,如果我要从TableAProcess向数据库进行100K调用, ve 100K TableA记录 。
如何通过使用Tasklet或其他方式将TableA
数据设置为SubDivision
的模型?
如何避免从Processor调用太多查询?
由于某些限制,我无法进行单个查询,因此我需要再向DB查询一个查询以获取细分数据。
TableA
型号
@Slf4j
public class TableAProcessor implements ItemProcessor<TableA, TableA>{
@Autowired
private TableADao tableADao;
@Override
public TableA process(TableA tableA) throws Exception {
log.debug("TableA DETAILS : "+tableA);
List<SubDivision> subDivisions = tableADao.getSubDivision(tableA.getPKId());
tableA.setSubDivisions(subDivisions);
return tableA;
}
}
TableABatchConfig.java
public class TableA {
@Transient
private Integer Id;
@Field
private String mongoId;
........
.......
@Field
private List<SubDivision> subDivisions;
}
TableAJob.java
@Configuration
public class TableABatchConfig {
private static final String sql = "SELECT * FROM TABLEA";
@Autowired
@Qualifier(value="oracleDataSource")
private DataSource dataSource;
@Bean(destroyMethod = "")
@StepScope
public JdbcCursorItemReader<TableA> TableAReader() throws Exception {
JdbcCursorItemReader<TableA> reader = new JdbcCursorItemReader<TableA>();
reader.setDataSource(this.dataSource);
reader.setSql(sql);
reader.setRowMapper(new TableARowMapper());
reader.afterPropertiesSet();
return reader;
}
@Bean
public ItemProcessor<TableA, TableA> TableAProcessor() {
return new TableAProcessor();
}
@Bean
public TableAWriter TableAWriter() {
return new TableAWriter();
}
}
dao
@Configuration
@PropertySource("classpath:application.properties")
public class TableAJob {
@Value( "${spring.chunk.size}")
private String chunkSize;
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private JdbcCursorItemReader<TableA> TableAReader;
@Autowired
private ItemProcessor<TableA, TableA> TableAProcessor;
@Autowired
private TableAWriter TableAWriter;
@Bean
public TableAStepExecuListner TableAStepExecuListner() {
return new TableAStepExecuListner();
}
@Bean("readTableAJob")
@Primary
public Job readTableAJob() {
return jobBuilderFactory.get("readTableAJob")
.incrementer(new RunIdIncrementer())
.start(TableAStepOne())
.build();
}
@Bean
public Step TableAStepOne() {
return stepBuilderFactory.get("TableAStepOne")
.<TableA, TableA>chunk(Integer.parseInt(chunkSize))
.reader(TableAReader)
.processor(TableAProcessor)
.writer(TableAWriter)
.listener(TableAStepExecuListner())
.build();
}
}
TableAWriter.java
@Service
public class TableADao {
private static final String SQL = "COMPLEX JOIN QUERY";
@Autowired
private JdbcTemplate jdbcTemplate;
public List<SubDivision> getSubDivision(Integer pkId){
List<Map<String, Object>> results = jdbcTemplate.queryForList(SQL,new Object[] { pkId });
List<SubDivision> divisions = new ArrayList<>();
for (Map<String, Object> row : results) {
divisions.add(SubDivision.builder().subDivisionCd((String)row.get("SUBDIVISION_CD"))
......
.........
.........
......
.build());
}
return divisions;
}
}