springboot项目 实现CSV文件百万数据入库

需要先引入解析工具

		<!--cvs 解析工具-->
		<dependency>
			<groupId>com.opencsv</groupId>
			<artifactId>opencsv</artifactId>
			<version>4.3.2</version>
		</dependency>

抽取出工具类

package io.renren.utils;

import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStreamReader;
import java.util.List;

public class cvsUtils {
    public static <T> List<T> getCsvData(MultipartFile file, Class<T> clazz) {
        InputStreamReader in = null;
        try {
            in = new InputStreamReader(file.getInputStream(), "gbk");
        } catch (Exception e) {
            System.out.println("读取文件失败");
        }

        HeaderColumnNameMappingStrategy<T> strategy = new HeaderColumnNameMappingStrategy<>();
        strategy.setType(clazz);

        CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(in)
                .withSeparator(',')
                .withQuoteChar('\'')
                .withMappingStrategy(strategy).build();
        return csvToBean.parse();
    }


}

案例demo

package io.renren.entity.csv;

import com.opencsv.bean.CsvBindByName;


public class User {


    @CsvBindByName(column = "id")
    private Long id;


    /**
     * 字典代码
     */
    @CsvBindByName(column = "code")
    private String code;

    /**
     * 简写
     */
    @CsvBindByName(column = "shortName")
    private String shortName;

    /**
     * N
     * 名称
     */
    @CsvBindByName(column = "name")  //是否可以为null 否
    private String name;


    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getShortName() {
        return shortName;
    }

    public void setShortName(String shortName) {
        this.shortName = shortName;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


}

下面是核心代码
使用线程池和java8Stream流数据分片去处理

配置好线程池 和 CompletableFuture 去做异步处理
线程池配置

package io.renren.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
public class ThreadPoolTaskExecutorConfig {
    @Bean("taskModuleExecutor")
    ThreadPoolTaskExecutor getCrawler1(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(5);
        threadPoolTaskExecutor.setMaxPoolSize(6);
        threadPoolTaskExecutor.setQueueCapacity(200);
        threadPoolTaskExecutor.setThreadNamePrefix("task-concurrent-work");
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

}```



//每一千条批量插入 (这里根据自己的需求去定义)
public static  final long PAGE_SIZE =1000;

@PostMapping("/uploadVCSBeach")
public R uploadVCSBeachThere(MultipartFile file) throws IOException {



    //cvs工具类解析数据
    List<User> userList = cvsUtils.getCsvData(file, User.class);

    if (CollectionUtils.isNotEmpty(userList)){

        //总页数
        long count = userList.size()/PAGE_SIZE;

        //遍历每一页
        for (Integer i = 1; i < count+1; i++) {
            int n =i;
		
		// 这里是做分片
        List<User> subUserList = userList.stream()
                .skip((n - 1) * PAGE_SIZE) //方法用于跳过前n条数据
                .limit(PAGE_SIZE) //方法用于返回前n条数据,
                .collect(Collectors.toList());
            try {
                CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {

                    // 批量插入
                    userDao.insertBatch(subUserList);
                }, threadPoolExecutor);
             //   CompletableFuture.allOf(voidCompletableFuture).get();

            } catch (Exception e) {
                e.printStackTrace();
            }

        }


    }

    return R.ok();
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot中读取CSV文件并进行数据映射,可以使用OpenCSV库。以下是实现步骤: 1. 添加OpenCSV依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>com.opencsv</groupId> <artifactId>opencsv</artifactId> <version>5.0</version> </dependency> ``` 2. 创建CSV文件读取器 创建一个CSV文件读取器,使用OpenCSV库的CSVReader类。该类提供了多种方法用于读取CSV文件中的数据。 ``` @Service public class CsvReaderService { public List<Employee> readEmployeesFromCsv(String filePath) throws IOException { List<Employee> employees = new ArrayList<>(); FileReader fileReader = new FileReader(filePath); CSVReader csvReader = new CSVReaderBuilder(fileReader).withSkipLines(1).build(); String[] line; while ((line = csvReader.readNext()) != null) { Employee employee = new Employee(); employee.setId(Integer.parseInt(line[0])); employee.setName(line[1]); employee.setAge(Integer.parseInt(line[2])); employee.setSalary(Double.parseDouble(line[3])); employees.add(employee); } csvReader.close(); return employees; } } ``` 在上述代码中,我们首先创建了一个CSVReader对象,然后使用while循环逐行读取CSV文件中的数据,并将其映射到Employee对象中。在每次迭代中,我们将Employee对象添加到employees列表中,并在最后关闭CSVReader对象。 3. 创建实体类 创建一个Employee实体类,用于将CSV文件中的数据映射到对象中。 ``` public class Employee { private int id; private String name; private int age; private double salary; // getters and setters } ``` 4. 使用CsvReaderService类读取CSV文件 在需要读取CSV文件的地方,注入CsvReaderService类并调用readEmployeesFromCsv方法。 ``` @Autowired private CsvReaderService csvReaderService; public void processCsvFile() throws IOException { List<Employee> employees = csvReaderService.readEmployeesFromCsv("employees.csv"); // Do something with employees } ``` 以上就是Spring Boot项目读取CSV文件并进行数据映射的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值