지역 정보 CSV 파일을 엔티티 객체로 Parsing하기 (@PostConstruct)

김건우·2023년 2월 2일
0

spring

목록 보기
5/9
post-thumbnail

해당 프로젝트에서 Zone이라는 지역 엔티티를 만들었다. 프로젝트에서 구상중인 것은 지역정보들의 값을 미리 데이터베이스에 값을 넣어주고 사용자가 지역정보를 선택할 수 있게 제작할 예정이다. 그렇기 위해서 csv파일을 이용하여 지역정보를 넣어줄 것 이다.

csv 파일로 변환 시킬 지역 정보 페이지
위의 지역정보에서 구글 독 스프레드시트에 값을 넣어주어 csv파일로 변환 시켜줄 것 이다. csv파일을 생성하여 resources안에 넣어준다🔽

그럼 위와 같이 지역정보를 Zone 엔티티와 parsing해주어야 한다.

Zone(지역)


@Entity
@Getter
@EqualsAndHashCode(of = "id")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"city", "province"}))
public class Zone {

    @Id @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String city;

    @Column(nullable = false)
    private String localNameOfCity;

    @Column(nullable = true)
    private String province;

    @Override
    public String toString() {
        return String.format("%s(%s)/%s", city, localNameOfCity, province);
    }

}

@PostConstruct란?

@PostConstruct는 의존성 주입이 이루어진 후 초기화를 수행하는 메서드이다. @PostConstruct가 붙은 메서드는 클래스가 service(로직을 탈 때? 로 생각 됨)를 수행하기 전에 발생한다. 이 메서드는 다른 리소스에서 호출되지 않는다해도 수행된다.

따라서 @PostConstruct를 사용하여 ZoneService가 Bean으로 등록된 이후에 실행이 되는 지점을 설정해주기위해 @PostConstruct를 선언해 줄 것이다.

📢지역 CSV 파일을 Zone(지역)과 parsing 해주는 서비스

  1. Zone(지역)의 repository에 데이터가 하나도 없다면 넣어줄 것이다.
  2. springframework.core.io.Resource를 이용하여 csv파일을 지정해준다.
  3. Files.readAllLines(resource.getFile().toPath(), StandardCharsets.UTF_8) 
    를 이용하여 전부 객체로 읽어 올 것이다.

    👨🏻‍💻중요
    stream의 map을 사용하여 ","로 문자열을 나누고 각각의 문자열을 ZONE의 필드에 파싱해줄 것 이다.
    한 줄씩 읽어서 문자열을 Zone객체로 파싱해주고 collect(Collectors.toList())를 이용하여 List형태로 반환해주자!

@Service
@Transactional
@RequiredArgsConstructor
public class ZoneService {
    private final ZoneRepository zoneRepository;

    @PostConstruct
    public void initZoneData() throws IOException {
        //지역 리소스가 하나도 없을 때
        if (zoneRepository.count() == 0) {
            //1.zones_kr.csv를 읽어온 다음
            //2.각 값을 ","를 split해주고
            //3.stream을 사용하여 Zone객체로 변환 시켜주자
            Resource resource = new ClassPathResource("zones_kr.csv");
            List<Zone> zoneList = Files.readAllLines(resource.getFile().toPath(), StandardCharsets.UTF_8)
                    .stream()
                    .map(line -> {
                        String[] split = line.split(",");
                        return Zone.builder()
                                .city(split[0])
                                .localNameOfCity(split[1])
                                .province(split[2]).build();
                    }).collect(Collectors.toList());
            zoneRepository.saveAll(zoneList);
        }
    }

}

Application을 실행하면 Zone에 값이 없을 때(zone을 생성하고 처음 실행 할 때) 다음과 같은 쿼리문이 나가는 것을 볼 수 있다.

  • 반복해서 나갈 것 이다.지역 정보의 갯수만큼🔽
Hibernate: 
    insert 
    into
        zone
        (city, local_name_of_city, province, id) 
    values
        (?, ?, ?, ?)
Hibernate: 
    insert 
    into
        zone
        (city, local_name_of_city, province, id) 
    values
        (?, ?, ?, ?)
Hibernate: 
    insert 
    into
        zone
        (city, local_name_of_city, province, id) 
    values
        (?, ?, ?, ?)
  • 데이터베이스에 들어간 지역정보 데이터🔽
profile
Live the moment for the moment.

0개의 댓글