본문 바로가기

Java

[Java] CSV 파일 데이터 불러오기

과제 수행 중 데이터를 입력하는 과정에서 다음과 같이 하드코딩으로 데이터를 입력했다.

@Component
@Order(1)
public class TestDataRunner implements ApplicationRunner {

    @Autowired
    ProductRepository productRepository;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Product product1 = createProduct((long) 768848, "[STANLEY] GO CERAMIVAC 진공 텀블러/보틀 3종", 21000, 45);
        Product product2 = createProduct((long) 748943, "디오디너리 데일리 세트 (Daily set)", 19000, 89);
        Product product3 = createProduct((long) 779989, "버드와이저 HOME DJing 굿즈 세트", 35000, 43);
        Product product4 = createProduct((long) 779943, "Fabrik Pottery Flat Cup & Saucer - Mint", 24900, 89);
        Product product5 = createProduct((long) 768110, "네페라 손 세정제 대용량 500ml 이더블유지", 7000, 79);
        Product product6 = createProduct((long) 517643, "에어팟프로 AirPods PRO 블루투스 이어폰(MWP22KH/A)", 260800, 26);
        Product product7 = createProduct((long) 706803, "ZEROVITY™ Flip Flop Cream 2.0 (Z-FF-CRAJ-)", 38000, 81);
        Product product8 = createProduct((long) 759928, "마스크 스트랩 분실방지 오염방지 목걸이", 2800, 85);
        Product product9 = createProduct((long) 213341, "20SS 오픈 카라/투 버튼 피케 티셔츠 (6color)", 33250, 99);
        Product product10 = createProduct((long) 377169, "[29Edition.]_[스페셜구성] 뉴코튼베이직 브라렛 세트 (브라1+팬티2)", 24900, 60);
        Product product11 = createProduct((long) 744775, "SHUT UP [TK00112]", 28000, 35);
        Product product12 = createProduct((long) 779049, "[리퍼브/키친마켓] Fabrik Pottery Cup, Saucer (단품)", 10000, 64);
        Product product13 = createProduct((long) 611019, "플루크 new 피그먼트 오버핏 반팔티셔츠 FST701 / 7color M", 19800, 7);
        Product product14 = createProduct((long) 628066, "무설탕 프로틴 초콜릿 틴볼스", 12900, 8);
        Product product15 = createProduct((long) 502480, "[29Edition.]_[스페셜구성] 렉시 브라렛 세트(브라1+팬티2)", 24900, 41);
        Product product16 = createProduct((long) 782858, "폴로 랄프로렌 남성 수영복반바지 컬렉션 (51color)", 39500, 50);
        Product product17 = createProduct((long) 760709, "파버카스텔 연필1자루", 200, 70);
        Product product18 = createProduct((long) 778422, "캠핑덕 우드롤테이블", 45000, 7);
        Product product19 = createProduct((long) 648418, "BS 02-2A DAYPACK 26 (BLACK)", 238000, 5);

        productRepository.save(product1);
        productRepository.save(product2);
        productRepository.save(product3);
        productRepository.save(product4);
        productRepository.save(product5);
        productRepository.save(product6);
        productRepository.save(product7);
        productRepository.save(product8);
        productRepository.save(product9);
        productRepository.save(product10);
        productRepository.save(product11);
        productRepository.save(product12);
        productRepository.save(product13);
        productRepository.save(product14);
        productRepository.save(product15);
        productRepository.save(product16);
        productRepository.save(product17);
        productRepository.save(product18);
        productRepository.save(product19);

    }

    public Product createProduct(Long productNumber, String productName, int productPrice, int productStock) {
        Product product = Product.builder()
                .productNumber(productNumber)
                .productName(productName)
                .productPrice(productPrice)
                .productStock(productStock)
                .build();
        return product;
    }
}

결과는 당연히 탈락...

그래서 이 코드를 아래와 같은 csv 파일을 불러와서 데이터를 입력하도록 바꿔보려고 한다.

 

@Component
@Order(1)
public class TestDataRunner implements ApplicationRunner {

    @Autowired
    ProductRepository productRepository;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        File file = new File("/Users/kimkiyun/Downloads/items_.csv");
        BufferedReader br = null;
        String line = "";

        try {
            br = new BufferedReader(new FileReader(file));
            while ((line = br.readLine()) != null) {
                List<String> aLine = new ArrayList<>();
                String[] lineArr = line.split(",");
				
                Product product = Product.builder()
                    .productNumber((long) Integer.parseInt(lineArr[0]))
                    .productName(lineArr[1])
                    .productPrice(Integer.parseInt(lineArr[2]))
                    .productStock(Integer.parseInt(lineArr[3]))
                    .build();
	            productRepository.save(product);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br == null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

코드를 짜고 실행해 보았는데 두가지 문제점이 발생했다.

 

첫번째로 첫번째 행의 컬럼명까지 불러오기 때문에 Product 생성시 데이터 타입이 일치하지 않아 에러가 발생했다.

그래서 일단 csv 파일에서 불러온 데이터를 리스트에 저장했다가 다시 for 문으로 1번 index 부터 조회하도록 코드를 수정했다.

 

두번째로 csv 파일은 ","로 행을 구분하는데 String으로 입력된 데이터에 ","가 포함되어 있어 split(",") 할때 배열의 크기가 일치하지 않아 문제가 발생했다.

이 문제는 split(",")을 split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)",-1) 으로 수정하여 "" 안에 있는 ,는 무시하도록 하여 문제를 해결하였다.

 

전체코드

@Component
@Order(1)
public class TestDataRunner implements ApplicationRunner {

    @Autowired
    ProductRepository productRepository;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        List<List<String>> csvList = new ArrayList<List<String>>();
        File file = new File("/Users/kimkiyun/Downloads/items_.csv");
        BufferedReader br = null;
        String line = "";

        try {
            br = new BufferedReader(new FileReader(file));
            while ((line = br.readLine()) != null) {
                List<String> aLine = new ArrayList<>();
                String[] lineArr = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)",-1);
                aLine = Arrays.asList(lineArr);
                csvList.add(aLine);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (br == null) {
                    br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        for (int i = 1; i < csvList.size(); i++) {
            Product product = Product.builder()
                    .productNumber((long) Integer.parseInt(csvList.get(i).get(0)))
                    .productName(csvList.get(i).get(1))
                    .productPrice(Integer.parseInt(csvList.get(i).get(2)))
                    .productStock(Integer.parseInt(csvList.get(i).get(3)))
                    .build();
            productRepository.save(product);
        }

    }

}

 

애플리케이션을 실행하고 상품 데이터를 조회해오는 메서드를 실행하면 다음과 같이 잘 들어간걸 확인할 수 있다.