1. 程式人生 > >spring boot + spring data jpa 批量插入 + POI讀取 + 檔案上傳

spring boot + spring data jpa 批量插入 + POI讀取 + 檔案上傳

說說自己玩 spring data jpa 遇到的一個坑

spring boot升級到2.0之後,就沒有下面這個方法了,如果要批量插入,還是要用1.5,給save方法傳一個list,直接可以批量插入,親測8w條資料沒問題;

下面帖程式碼,從頁面上傳一個excel,讀取8萬行表格資料之後,插入資料庫

pom.xml:

<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>
1.5.10.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
   </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.14</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> <version>1.5.9</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.4.0</version> </dependency> </dependencies>

application.yml :

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/data_test
    username: root
    password: root
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
  http:
      multipart:
        max-file-size: 20MB
        max-request-size: 20MB

在templates資料夾下新建一個html:


<!DOCTYPE html>
<html>
<head>
    <title>upload</title>
    <meta name="keywords" content="keyword1,keyword2,keyword3"></meta>
    <meta name="description" content="this is my page"></meta>
    <meta name="content-type" content="text/html; charset=UTF-8"></meta>
</head>
<body>
<form enctype="multipart/form-data" method="post" action="/upload/excel">
檔案<input type="file" name="file"/>
    <input type="submit" value="上傳"/>
</form>
</body>
</html>

然後是controller層:

import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class UploadController {


    @Autowired
private ExcelService excelService;
//跳轉到上傳檔案的頁面
@RequestMapping(path = "/upload", method = RequestMethod.GET)
    public String goUpload() {
        //跳轉到 templates 目錄下的 upload.html
return "upload";
}

    

    @ApiOperation(value = "匯入Excel表", notes = "", httpMethod = "POST")
    @RequestMapping(path = "/upload/excel",method = RequestMethod.POST)
    @ResponseBody
public String upload(MultipartFile file) throws Exception {
        excelService.getExcel(file);
        return "上傳成功";
}

然後是service層:

@Service
public class ExcelServiceImpl implements ExcelService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private ExcelRepository excelRepository;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void getExcel(MultipartFile file) throws Exception {
        List<Excel> list = new ArrayList<Excel>();
//1.得到上傳的表
Workbook workbook2 = WorkbookFactory.create(file.getInputStream());
//2、獲取sheet1工作表
Sheet sheet2 = workbook2.getSheet("sheet1");
//獲取表的總行數
int num = sheet2.getLastRowNum();
//總列數
int col = sheet2.getRow(0).getLastCellNum();

     //遍歷excel每一行
        for (int j = 1; j < num; j++) {
            Row row1 = sheet2.getRow(j);
//獲取表中第i行,第2列的單元格
Cell cell3 = row1.getCell(1);
//excel表的第i行,第3列的單元格
Cell cell4 = row1.getCell(2);
            //如果單元格中有數字或者其他格式的資料,則呼叫setCellType()轉換為string型別Cell cell7 = row1.getCell(4);
cell7.setCellType(CellType.STRING);
      //這裡new 一個物件,用來裝填從頁面上傳的Excel資料,欄位根據上傳的excel決定
            Excel excel= new Excel();
      excel.setName(cell3.getStringCellValue());
excel.setAge(cell4.getStringCellValue());excel.setAddress(cell7.getStringCellValue());list.add(command);} excelRepository.save(list);//批量插入資料}

然後是Repository:

@Repository
public interface ExcelRepository extends CrudRepository<Excel,Long> {

}

這裡的repository不需要寫任何方法,預設繼承了CrudRepository就有了jpa的增刪改查的方法,具體用法可以查官網的api

這裡注意CrudRepository<Excel,Long> 表示要用該方法對Excel實體類做增刪改查

下面是實體類:

@Entity
@Table(name = "excel_test")
public class Excel {
    
    @Id
    @GeneratedValue
private Integer id;
@Column
private String name;
@Column
private String age;
@Column
private String address;
    //省略getter,setter
}

用了上面這些註解之後,服務啟動,spring jpa就會在資料庫生成相應的表,然後跑起來

訪問:localhost:8080/upload  ,上傳一個8w條的帶有name,age,address欄位的excel表,就會批量插入到資料庫了