백엔드 개발에서 초기 데이터를 설정할 때, 하드코딩으로 값을 입력하는 경우가 많습니다. 하지만 데이터가 많아질수록 코드가 복잡해지고 관리가 어려워지죠. 이번 포스팅에서는 하드코딩 대신 CSV 파일을 활용하여 데이터를 초기화하는 방법과, 그 과정에서 발생한 문제를 어떻게 해결했는지 소개합니다.
1. 하드코딩 방식의 문제점
처음에는 아래와 같이 데이터를 직접 코드에 하드코딩하여 초기화했습니다.
@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);
...
productRepository.save(product1);
productRepository.save(product2);
...
}
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;
}
}
하드 코딩 방식에는 아래와 같은 문제점이 있었습니다.
- 데이터 수정의 어려움: 데이터를 변경할 때마다 코드를 수정하고 재배포해야 했습니다.
- 가독성 저하: 데이터가 많아질수록 코드가 복잡해지고 유지보수가 어려워졌습니다.
2. CSV 파일을 활용한 데이터 입력
위 문제를 해결하기 위해 데이터를 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();
}
}
}
}
3. 문제 해결 과정
CSV 데이터를 읽어오면서 두 가지 문제가 발생했습니다.
문제 1. 첫 번째 행(컬럼명) 처리 문제
- CSV 파일의 첫 번째 행은 데이터가 아니라 컬럼명이므로, 이를 무시해야 했습니다.
- 해결 방법: 데이터를 저장하기 전에 첫 번째 행을 건너뛰도록 for문을 수정했습니다.
for (int i = 1; i < csvList.size(); i++) { // 첫 번째 행 제외
// 데이터 저장 로직
}
문제 2. 데이터 내 포함된 , 처리 문제
- CSV 파일은 ","로 행을 구분하는데 CSV 데이터에서 ""로 감싸진 값 내부에 ','가 포함된 경우, split(",")으로 제대로 나뉘지 않아 오류가 발생했습니다.
- 해결 방법: 정규식을 활용해 CSV 파일의 구조를 정확히 파싱했습니다.
String[] lineArr = line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)", -1);
이 정규식은 큰따옴표 내부의 쉼표는 무시하고 데이터를 분리할 수 있도록 합니다.
전체코드
애플리케이션을 실행하고 상품 데이터를 조회해오는 메서드를 실행하면 다음과 같이 잘 들어간걸 확인할 수 있습니다.
'Java' 카테고리의 다른 글
[Java] 이것이 자바다 - 상속 (1) | 2023.07.04 |
---|---|
[Java] 인접행렬, 인접리스트 (0) | 2023.02.28 |
[Java] 정적 멤버와 static (0) | 2023.02.23 |
[Java] 이것이 자바다 - IO 패키지 (2) | 2022.06.20 |
[Java] 이것이 자바다 - 멀티 프로세스, 멀티 스레드 (0) | 2022.06.06 |