Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring batch上载CSV文件并相应地插入数据库_Java_Spring_Spring Batch - Fatal编程技术网

Java Spring batch上载CSV文件并相应地插入数据库

Java Spring batch上载CSV文件并相应地插入数据库,java,spring,spring-batch,Java,Spring,Spring Batch,我的项目有这样的要求,用户上传一个CSV文件,该文件必须推送到mysql数据库。我知道我们可以使用Spring批处理来处理大量记录。但是我找不到任何教程/示例代码来满足我的这个需求。我遇到的所有教程都只是将CSV文件名硬编码在其中,如下所示: 我需要使用用户上传的文件,并进行相应的处理。如蒙帮助,不胜感激 如果没有使用SpringBatch,是否有其他方法将上传的CSV数据插入mysql?我将SpringMVC(RestController)和SpringBatch混合使用。SpringMVC

我的项目有这样的要求,用户上传一个CSV文件,该文件必须推送到mysql数据库。我知道我们可以使用Spring批处理来处理大量记录。但是我找不到任何教程/示例代码来满足我的这个需求。我遇到的所有教程都只是将CSV文件名硬编码在其中,如下所示:

我需要使用用户上传的文件,并进行相应的处理。如蒙帮助,不胜感激


如果没有使用SpringBatch,是否有其他方法将上传的CSV数据插入mysql?

我将SpringMVC(RestController)和SpringBatch混合使用。SpringMVC帮助将csv文件作为多部分请求上传。然后,通过将上传的csv传递给Spring作业,我异步调用了SpringBatch。Spring作业收到csv文件后,通过读取、处理和写入DB作业进行Spring批处理。

请将此作为主要参考: 这说明了如何使用批处理将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));
@Bean
公共FlatFileItemReader导入程序(@Value(“#{jobParameters[fullPathFileName]}”)字符串路径文件){
FlatFileItemReader=新的FlatFileItemReader();
setResource(新文件系统资源(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";
    }

}
@配置
@启用批处理
公共类BatchConfig{
@豆子
公共资源事务管理器batchTransactionManager(){
ResourceLessTranslationManager transactionManager=新建ResourceLessTranslationManager();
返回事务管理器;
}
@豆子
受保护的JobRepository JobRepository(ResourcelessTransactionManager batchTransactionManager)引发异常{
MapJobRepositoryFactoryBean jobRepository=新的MapJobRepositoryFactoryBean();
jobRepository.setTransactionManager(batchTransactionManager);
return(JobRepository)JobRepository.getObject();
}
@豆子
公共JobLauncher JobLauncher(JobRepository JobRepository)引发异常{
SimpleJobLauncher jobLauncher=新的SimpleJobLauncher();
jobLauncher.setJobRepository(jobRepository);
返回作业启动器;
}
}
@配置
公共类ImportJobConfig{
@豆子
公共FlatFileItemReader导入程序(@Value(“#{jobParameters[fullPathFileName]}”)字符串路径文件){
FlatFileItemReader=新的FlatFileItemReader();
setResource(新文件系统资源(pathToFile));
reader.setLineMapper(新的DefaultLineMapper(){{
setLineTokenizer(新的DelimitedLineTokenizer(){{
setNames(新字符串[]{“firstName”,“lastName”});
}});
setFieldSetMapper(新的BeanRapperFieldSetMapper(){{
setTargetType(Person.class);
}});
}});
返回读取器;
}
@豆子
公共PersonItemProcessor处理器(){
返回新的PersonItemProcessor();
}
@豆子
公共JdbcBatchItemWriter编写器(){
JdbcBatchItemWriter writer=新的JdbcBatchItemWriter();
writer.setItemSqlParameterSourceProvider(
新BeanPropertyItemSqlParameterSourceProvider());
setSql(“插入人(名字、姓氏)值(:firstName,:lastName)”;
writer.setDataSource(dataSource);
返回作者;
}
//end::readerwriterprocessor[]
//标记::作业步骤[]
@豆子
公共作业导入器作业(作业完成通知侦听器侦听器){
返回jobBuilderFactory.get(“importUserJob”).incrementer(新的RunIdIncrementer())
.listener(listener).flow(step1()).end().build();
}
@豆子
公共步骤步骤1(@Qualifier(“importrader”)ItemReader importrader){
返回stepBuilderFactory.get(“step1”).chunk(10).reader(importrader)
.processor(processor()).writer(writer()).build();
}
}
@RestController
公共类MyImportController{
@自动连线专用JobLauncher JobLauncher;
@自动连线私人作业导入作业;
@RequestMapping(value=“/import/file”,method=RequestMethod.POST)
公共字符串创建(@RequestParam(“file”)MultipartFile MultipartFile)引发IOException{
//将多部分文件保存在临时物理文件夹中
String path=new ClassPathResource(“tmpuploads/”).getURL().getPath();//假定资源文件夹中有一个名为tmpuploads的文件夹
File fileToImport=新文件(路径+multipartFile.getOriginalFilename());
OutputStream OutputStream=新文件OutputStream(fileToImport);
copy(multipartFile.getInputStream(),outputStream);
outputStream.flush();
outputStream.close();
//启动批处理作业
JobExecution JobExecution=jobLauncher.run(importUserJob,new JobParametersBuilder()
.addString(“fullPathFileName”,fileToImport.getAbsolutePath())
.toJobParameters());
返回“OK”;
}
}

Spring批处理在您希望连续运行某个作业时非常有用,可以从某个位置获取输入,对其进行处理并将其保存到某个位置。它的主要优点是Spring将在单独的线程中执行这三个步骤,并且可以以chuunks形式执行此操作。这节省了时间和空间复杂性。在您的情况下,它必须是tr我关注用户操作,所以我认为spring批处理在这种情况下并不理想。