Bulk Excel Data Insert 1부

2022. 6. 20. 00:48Spring/JPA

엑셀을 사용하여 Bulk 차량 등록하기 기능 구현하기

차량등록하기 기능 분석

  • 현재 다니고 있는 회사는 모빌리티 회사여서 단건 차량등록하기 기능이 있다. (ADMIN 페이지에서) 최근 운영팀에서 업체별로 등록해야하는 차량들이 증가하고 있기 때문에 여러차량들을 등록 할 수 있는 기능을 구현해달라고 기획자분에게 요청하였다.
  • 이 기능 구현을 내가 맡게 되었는데, 기존 단건 차량 로직을 분석 후 기능을 구현하기로 하였다.

기존 단건 기능 로직

  1. 등록 요청할 때 업체 , 지점 을 DB에서 조회하여 없을 때는 InvalidParameterException 을 호출하고 있다.
  2. validateDuplicateCar 메서드로 DB에서 중복차량 검사를 하고 있다.
    (차량번호 Pattern은 @Vaildation 어노테이션을 사용하여 RequestDTO 에서 체크하고 있었다.)
  3. 요청된 Data를 알맞게 DTO 팩터리 메서드로 Entity에 넣어주고 있었고, carRepository.save()를 사용하여 저장을 하고있었다. 또한 마지막에 CarCheckupStatus Entity에 Default 데이터를 저장하고 있었다. → 이 부분으로 인한 아주 큰 사건이 터지게된다... 다음 회고록에서 작성해야지..😇

Spring Boot 라이브러리 (Poi) 사용하기 도전...

  • 처음에 생각했던것은 Poi 라이브러리를 사용해서 엑셀 업로드를 구현하고 Controller에서 데이터를 받아야겠다. 라고 생각하고 기능을 만들려고 하였다.
    2022-06-19-17-41-36.png

    • 다음과 같이 라이브러리를 추가한다.
  • 하지만 버전에서 Beta 버전이 있고, 버전마다 Cell 데이터를 읽어오는 방식이 천차만별이어서 개발에 속도가 나지 않았다.

    whitch(cell.getCellType()){
    case HSSHSSFCell.CELL_TYPE_NUMERIC: 
    
         value =  cell.getNumericCellValue();
    
         break;
    
    case HSSHSSFCell.CELL_TYPE_STRING: 
    
         value =  cell.getStringCellValue();
    
         break;
    }

이런 방법으로 CellType을 검사하면서 Cell 값을 받아야하지만 , 몇몇 Version에서는 getCellType() 메서드 자체를 지원중단하였다.
2022-06-19-17-48-30.png | 200
라이브러리 별로 찾아보면서 지원을 하는지 안하는지 체크해야한다... 후아..
2022-06-19-17-50-18.png | 200

  • POi 라이브러리의 다양한 Beta 버전 및 정식 버전들..

웹 브라우저에서 ExcelUpload

  • POI 라이브러리를 활용해서 Excel 데이터를 읽기는 다음기회에... 다음에 토이 프로젝트로 혼자서 POI라이브러리로 엑셀 Uplocad & Download를 구현해봐야겠다.🤔
  • ADMIN 페이지는 React 로 구현되어있다.
  • FileReader(), XLSX.read() 를 사용하여 엑셀 파일의 데이터를 JSON으로 변경하여 Controller 로 보냈다.
  • 또한 파일 형식은 .csv, .xlsx, .xls 만 허용할 수 있게 하였다.

    사용예시

readExcel(acceptedFiles) {   
    if (acceptedFiles[0].path.match('xlsx') || acceptedFiles[0].path.match('csv') || acceptedFiles[0].path.match('xls')) {  
        this.setState({registerBtnDisabled:true})  
        let that = this  
        let reader = new FileReader();  
        let rows;  
        reader.readAsBinaryString(acceptedFiles[0]);  
        reader.onload = function () {  
        new Promise((res, rej) => {  
                let data = reader.result;  
                let workBook = XLSX.read(data, { type: 'binary' });  
                workBook.SheetNames.forEach(function (sheetName) {  
                    rows = XLSX.utils.sheet_to_json(workBook.Sheets[sheetName]);  
    if(rows.length === 0){  
                        rej('데이터가 없거나 형식이 맞지 않습니다.')  
                    }                    res(rows)  
                })            }).then((result)=>{  
                that.setState({carList:result})  
            }).catch((err) => {  
                중략()...
            }).finally(() => {  
                if(that.state.carList.length > 0){  
                    that.setState({registerBtnDisabled:false});  
                }  
            })        
        };  
    } else {  
        중략()...  
}    
  • 하나의 메서드로 깔끔하게 끝나버렸다!

Excel 데이터 Request 마무리를 하며..

  • 서버로 MultiPartFile 매개변수로 Excel 파일을 넘겨받으면서 POI 라이브러리를 사용해서 처리를 하려 하였지만 생각보다 POI 가 깔끔하게 정리되지 않았고, 엑셀 다운로드 개발 with 우아한 형제들 최태현님이 작성하신 엑셀 다운로드 로직 처럼 추상화와 자체적으로 구현하지 않고는 중구난방으로 로직이 만들어질거 같아 브라우저에서 File 을 처리하는 것이 더 깔끔하게 코드를 작성할 수 있을거같아서 위와 같이 React 에서 구현하게 되었다.
  • 어떻게 보면 서버단에서 MultipartFile로 받아서 구현을 하게되면 저는 가성비 라고 부는데 ..! 가성비가 나오지 않아 브라우저에서 처리했지만, POI를 사용해서 토이 프로젝트로 해봐야겠다.
  • 다음에는 요청한 데이터를 가지고 Bulk Insert를 하는 방법에 대해서 설명하겠다.

'Spring > JPA' 카테고리의 다른 글

Bulk Exel Data Insert 2부  (0) 2022.06.20
Java8 Stream 특정 Key 중복제거  (0) 2022.05.30
JPQL은 만능이 아니다!  (0) 2021.12.23
[Spring JPA] 즉시로딩과 지연로딩  (0) 2021.06.28
Spring JPA [상속관계 맵핑]  (0) 2021.06.17