본문 바로가기

Dev/Spring Boot

Spring Boot JPA - BufferedReader로 CSV 파일을 읽어 DB에 저장하기

728x90

BufferedReader

자바에서 입출력을 빠르게 받을 때 많이 사용했던 버퍼리더, 정확히 버퍼 리더가 무엇인가
버퍼란 어떤 데이터가 전송 될 때 일시적으로 저장되는 영역이다. (캐시와는 다르다.) 어떤 데이터들을 한 번에 묶어서 전송하기 때문에 전송이 빠르다.

    BufferedReader br = Files.newBufferedReader(Paths.get(filePath));

map을 사용해 임시 값 저장

csv파일은 ,로 구분된 정보를 엑셀 형태로 보여주는 파일이다. 그러니까 텍스트로 옮기면

이름, 나이, 사는곳
김, 20, 서울
박, 21, 부산

이런식으로 구성되어 있다. 버퍼리더로 값을 받으면 한 행씩 정보를 받지 열(col)씩 받지 않기 때문에 맨 위 헤더들을 key값으로 갖는 hashmap을 만들어 놓고 값을 구성한다.

List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();

        List<String> headerList = new ArrayList<String>();

        try{
            BufferedReader br = Files.newBufferedReader(Paths.get(filePath));
            String line = "";

            while((line = br.readLine()) != null){
                List<String> stringList = new ArrayList<>();

                String[] stringArray = line.split(",");

                stringList = asList(stringArray);

                // csv 1열 데이터를 header로 인식
                if(headerList.isEmpty()){
                    headerList = stringList;
                } else {
                    Map<String, Object> map = new HashMap<String, Object>();
                    // header 컬럼 개수를 기준으로 데이터 set
                    int idx = Math.min(headerList.size(), stringList.size());
                    if(headerList.size() != stringList.size()) continue;
                    for(int i = 0; i < idx; i++){
                        map.put(headerList.get(i), stringList.get(i));
                    }
                    mapList.add(map);
                }
            }
        }catch (Exception e){
            e.printStackTrace();

            return fileName + " 파일 읽던 중 문제 발생";
        }

그리고 해시맵을 해시맵 리스트에 넣는다. 리스트에 넣는 이유는 이후에 디비에 넣기 위해 모든 해시값을 다시 돌아야하기 때문이다.

try{
            toilet t = toiletRepository.findAll().get(0);

            for (Map<String, Object> Info : mapList) {
                t.getSeoul().add(toiletInfo.builder()
                        .name((String) Info.get("화장실명"))
                        .address((String) Info.get("소재지도로명주소"))
                        .openTime((String) Info.get("개방시간상세"))
                        .office((String) Info.get("관리기관명"))
                        .X((String) Info.get("WGS84위도"))
                        .Y((String) Info.get("WGS84경도"))
                        .build());
            }
        }catch (Exception e){
            return fileName + " DB삽입 중 문제 발생";
        }

        return fileName + " 화장실 정보 삽입 성공";
    }

난 JPA의 레포지토리 기능과 영속성 컨텍스트로 간편하게 값을 저장하였다.