私のプロジェクトには、ユーザーがmysqlデータベースにプッシュする必要があるCSVファイルをアップロードするというこの要件があります。 Springバッチを使用して多数のレコードを処理できることはわかっています。しかし、私のこの要件のチュートリアル/サンプルコードを見つけることができません。私が遭遇したすべてのチュートリアルは、CSVファイル名を以下のようにハードコーディングしました。
https://spring.io/guides/gs/batch-processing/
ユーザーがアップロードしたファイルを使用して、それに応じて処理する必要があります。ここでの助けをいただければ幸いです。
Springバッチを使用していない場合、アップロードされたCSVデータをmysqlに挿入する他の方法はありますか?
これを主な参考資料としてください: http://walkingtechie.blogspot.co.uk/2017/03/spring-batch-csv-file-to-mysql.html これは、Batchを使用してCSVファイルをMySQLデータベースにインポートします。
ただし、あなたが言ったように、すべての例はあなたが望むものではないハードコードファイルを想定しています。
以下のコードでは、重要なビット(私が提供したリンクの例とは異なります)は、マルチパートファイルを取得して一時フォルダーに保存するコントローラーです。次に、ファイル名がパラメーターとしてジョブに渡されます。
JobExecution jobExecution = jobLauncher.run(importUserJob, new JobParametersBuilder()
.addString("fullPathFileName", fileToImport.getAbsolutePath())
.toJobParameters());
最後に、importReaderはparam fullPathFileNameを使用して、ユーザーがアップロードしたファイルをロードします。
@Bean
public FlatFileItemReader<Person> importReader(@Value("#{jobParameters[fullPathFileName]}") String pathToFile) {
FlatFileItemReader<Person> reader = new FlatFileItemReader<>();
reader.setResource(new FileSystemResource(pathToFile));
ここにあなたにアイデアを与えるための完全なコード(テストされていませんが、ほとんどのコンポーネントが含まれています):
@Configuration
@EnableBatchProcessing
public class BatchConfig{
@Bean
public ResourcelessTransactionManager batchTransactionManager(){
ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager();
return transactionManager;
}
@Bean
protected JobRepository jobRepository(ResourcelessTransactionManager batchTransactionManager) throws Exception{
MapJobRepositoryFactoryBean jobRepository = new MapJobRepositoryFactoryBean();
jobRepository.setTransactionManager(batchTransactionManager);
return (JobRepository)jobRepository.getObject();
}
@Bean
public JobLauncher jobLauncher(JobRepository jobRepository) throws Exception {
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository);
return jobLauncher;
}
}
@Configuration
public class ImportJobConfig {
@Bean
public FlatFileItemReader<Person> importReader(@Value("#{jobParameters[fullPathFileName]}") String pathToFile) {
FlatFileItemReader<Person> reader = new FlatFileItemReader<>();
reader.setResource(new FileSystemResource(pathToFile));
reader.setLineMapper(new DefaultLineMapper<Person>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[]{"firstName", "lastName"});
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}});
}});
return reader;
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public JdbcBatchItemWriter<Person> writer() {
JdbcBatchItemWriter<Person> writer = new JdbcBatchItemWriter<>();
writer.setItemSqlParameterSourceProvider(
new BeanPropertyItemSqlParameterSourceProvider<Person>());
writer.setSql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)");
writer.setDataSource(dataSource);
return writer;
}
// end::readerwriterprocessor[]
// tag::jobstep[]
@Bean
public Job importUserJob(JobCompletionNotificationListener listener) {
return jobBuilderFactory.get("importUserJob").incrementer(new RunIdIncrementer())
.listener(listener).flow(step1()).end().build();
}
@Bean
public Step step1(@Qualifier("importReader") ItemReader<Person> importReader) {
return stepBuilderFactory.get("step1").<Person, Person>chunk(10).reader(importReader)
.processor(processor()).writer(writer()).build();
}
}
@RestController
public class MyImportController {
@Autowired private JobLauncher jobLauncher;
@Autowired private Job importUserJob;
@RequestMapping(value="/import/file", method=RequestMethod.POST)
public String create(@RequestParam("file") MultipartFile multipartFile) throws IOException{
//Save multipartFile file in a temporary physical folder
String path = new ClassPathResource("tmpuploads/").getURL().getPath();//it's assumed you have a folder called tmpuploads in the resources folder
File fileToImport = new File(path + multipartFile.getOriginalFilename());
OutputStream outputStream = new FileOutputStream(fileToImport);
IOUtils.copy(multipartFile.getInputStream(), outputStream);
outputStream.flush();
outputStream.close();
//Launch the Batch Job
JobExecution jobExecution = jobLauncher.run(importUserJob, new JobParametersBuilder()
.addString("fullPathFileName", fileToImport.getAbsolutePath())
.toJobParameters());
return "OK";
}
}
Spring MVC(RestController)とSpringBatchを組み合わせて作成しました。 Spring MVCは、csvファイルをマルチパートリクエストとしてアップロードするのに役立ちました。次に、このアップロードされたCSVをSpring Jobに渡すことで、Springバッチを非同期的に呼び出しました。 Springジョブがcsvファイルを受信すると、DBジョブの読み取り、処理、および書き込みによってSpringバッチ処理を実行しました。