[SpringBoot + JPA]공공데이터 API를 DB에 저장해보자 - 3

·4일 전
0
post-thumbnail

💡JPA를 이용해서 API를 DB에 저장해보자

  • 이전까지는 JSON데이터 자체를 JAVA에서 출력하는 것을 했는데, API 데이터를 활용하기 위해서는 JSON데이터를 파싱하여 내가 원하는 형태로 JPA에 저장해보도록 하겠다.

📗Entity 구현

  • 우선 Entity를 구현해 보도록 하겠다. API에서 제공하는 필드들은 여러가지지만 내가 원하는 필드들만 가져오도록 Entity를 설계했다.
@Getter
@Entity
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
public class LocationDomain {
    @Id
    private Long locationCode;      //행정동코드
    @NotNull
    private String locationName;    //행정동명
    @NotNull
    private String revisedDate;     //개정날짜

    @Builder
    public LocationDomain(Long locationCode, String locationName, String revisedDate) {
        this.locationCode = locationCode;
        this.locationName = locationName;
        this.revisedDate = revisedDate;

    }
}

API 필드 중 행정동 코드, 행정동명, 개정 날짜만 가져오도록 Entity를 구성했다.

📗Repository 구현

public interface LocationRepository extends JpaRepository<LocationDomain, Long> {
}

📗Service 구현

@Service
public class ApiExplorer implements CommandLineRunner {

    @Autowired
    private LocationRepository locationRepository;

    @Override
    public void run(String... args) throws Exception {
        int page = 1;
        boolean hasMoreData = true;
        ObjectMapper objectMapper = new ObjectMapper(); // JSON 파싱용
        //중복 방지용 set
        Set<Long> uniqueCodes = new HashSet<>();
        //최종 데이터 저장용 list
        List<LocationDomain> DataList = new ArrayList<>();


        while (hasMoreData) {
            // 1. URL 생성
            StringBuilder urlBuilder = new StringBuilder("https://api.odcloud.kr/api/15136373/v1/uddi:84f86747-7012-4d74-b4c6-9d5068312ac4");
            urlBuilder.append("?").append(URLEncoder.encode("page", StandardCharsets.UTF_8)).append("=").append(page);
            urlBuilder.append("&").append(URLEncoder.encode("perPage", StandardCharsets.UTF_8)).append("=").append("10000");
            urlBuilder.append("&").append(URLEncoder.encode("returnType", StandardCharsets.UTF_8)).append("=").append("JSON");
            urlBuilder.append("&").append(URLEncoder.encode("serviceKey", StandardCharsets.UTF_8))
                    .append("=taoPZY395PqfMgnAZMcUnm/fxpYemRwZ8E30EfFyoDRAaQwbmou/fcvoq6DpixOwN0WGOBUrEdxCnk1gO17RAQ==");

            URL url = new URL(urlBuilder.toString());
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Content-type", "application/json");
            System.out.println("Response code: " + conn.getResponseCode());

            // 전달받은 데이터를 BufferedReader 객체로 저장.
            StringBuilder sb = new StringBuilder();
            try (BufferedReader rd = (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300)
                    ? new BufferedReader(new InputStreamReader(conn.getInputStream()))
                    : new BufferedReader(new InputStreamReader(conn.getErrorStream()))) {

                String line;
                while ((line = rd.readLine()) != null) {
                    sb.append(line);
                }
                // JSON 파싱
                JsonNode jsonNode = objectMapper.readTree(sb.toString());
                JsonNode dataArray = jsonNode.get("data");

                if (dataArray == null || !dataArray.isArray() || dataArray.isEmpty()) {
                    hasMoreData = false; // 더 이상 데이터가 없으면 종료
                    System.out.println("✅모든 데이터 불러오기 완료");
                } else {
                    for (JsonNode node : dataArray) {
                        long locationCode = node.path("행정동코드").asLong();
                        String revisedDate = node.path("개정일자").asText(null);

                        //데이터 중복 제거 후 저장
                        if (uniqueCodes.add(locationCode)) {
                            LocationDomain data = LocationDomain.builder()
                                    .locationCode(locationCode)
                                    .locationName(node.path("행정동명").asText(null))
                                    .revisedDate(node.path("개정일자").asText(null))
                                    .build();

                            DataList.add(data);
                        }
                    }

                    System.out.println("페이지: " + page + ", 체크된 데이터: " + DataList.size());
                    page++;  // Go to the next page
                }
            }
        }
        if (!DataList.isEmpty()) {
            locationRepository.saveAll(DataList);
            System.out.println("✅ 데이터 저장 완료");
        }
        for (Object item : DataList) {
            System.out.println(item);
        }
    }
}
  • 이전에 java로 json객체를 받았을 때 코드와 거의 비슷하다.
  • @Autowired로 locationRepository를 주입받고, 내가 가져온 API에는 중복되는 데이터가 많아서 중복을 방지하는 HashSet객체, 최종 데이터를 저장하는 List 객체를 지정한다.
  • 각 페이지당 데이터를 읽고, for문을 이용하여 행정동코드와 개정일자를 저장하고, 중복된 데이터가 없으면 Bulider패턴을 이용하여 행정동 코드, 행정동명, 개정일자를 LocationDomain에 저장한다.
  • 모든 데이터 읽기가 끝나면, saveAll()을 이용하여 데이터를 DB에 저장한다.

  • 데이터가 제대로 들어간 것을 확인할 수 있다.
profile
백엔드 개발자를 꿈꿉니다 / 이전 블로그 : https://po-dadak.tistory.com/category

0개의 댓글

관련 채용 정보