spring boot + spring data jpa 批量插入 + POI讀取 + 檔案上傳
阿新 • • 發佈:2019-02-17
說說自己玩 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表,就會批量插入到資料庫了