Я работаю над пакетным приложением Spring. Это приложение считывает данные из БД, обрабатывает и отправляет в Кафку. Мне нужно прочитать данные из двух таблиц в родительско-дочерних отношениях.
Как:
Родитель: - Id, Name
Child: - Id, Name, Parent_Id
Я использую JpaPagingItemReader. Я читаю данные родительской таблицы из программы чтения и дочерние данные из процесса.
@Autowired
private JpaTransactionManager transactionManager;
@PersistenceContext
private EntityManager em;
public ItemStreamReader<Parent> reader() {
JpaPagingItemReader<Parent> itemReader = new JpaPagingItemReader<>();
try {
String sqlQuery = "SELECT * FROM PARENT";
JpaNativeQueryProvider<Parent> queryProvider = new JpaNativeQueryProvider<Parent>();
queryProvider.setSqlQuery(sqlQuery);
queryProvider.setEntityClass(Parent.class);
queryProvider.afterPropertiesSet();
itemReader.setEntityManagerFactory(em.getEntityManagerFactory());
itemReader.setPageSize(100);
itemReader.setQueryProvider(queryProvider);
itemReader.afterPropertiesSet();
itemReader.setSaveState(true);
}
catch (Exception e) {
System.out.println("BatchConfiguration.reader() ==> error " + e.getMessage());
}
return itemReader;
}
@Autowired
private ChildRepository childRepository;
@Bean
public ItemProcessor<Parent,ParentVO> opptyProcess() {
return new ItemProcessor<Parent, ParentVO>() {
@Override
public ParentVO process(Parent parent) throws JsonProcessingException {
ParentVO parentVO = new ParentVO();
parentVO.setId(parent.getId());
parentVO.setName(parent.getName());
List<Child> childList = childRepository.findByParentId(parent.getId());
if(childList != null && childList.size() > 0) {
for(Child child :childList) {
ChildVo childVO= new ChildVO();
childVO.setId(child.getId);
childVO.setName(child.getName());
childVO.setParentId(child.getParentId())
ParentVO.getChildList().add(childVO);
}
}
return parentVO;
}
};
}
@Bean
public Step step() {
return stepBuilderFactory.get("step1")
.<Parent, ParentVO>chunk(100)
.reader(reader())
.processor(process())
.writer(writer)
.taskExecutor(threadPool)
.transactionManager(transactionManager)
.throttleLimit(10)
.build();
}
Я тестирую это приложение с записями по 20 тыс. Производительность этого приложения очень низкая. Каждую минуту он может читать / обрабатывать / писать только 100 записей. Если я прокомментирую приведенную ниже строку, выполнение задания займет 2 минуты.
List<Child> childList = childRepository.findByParentId(parent.getId());
if(childList != null && childList.size() > 0) {
for(Child child :childList) {
ChildVo childVO= new ChildVO();
childVO.setId(child.getId);
childVO.setName(child.getName());
childVO.setParentId(child.getParentId())
ParentVO.getChildList().add(childVO);
}
}
Что я могу сделать, чтобы получить данные таблицы Child и ускорить выполнение этого задания.