개발자

스프링부트 서비스 코드 작성 기법

2023년 11월 10일조회 62

현재 학교에서 웹서비스를 만드는 프로젝트를 진행하고있습니다 진행하는 프로젝트의 코드 중 일부분이 저로서는 이해가 잘 안되는 코드가 있어서 질문드립니다 Service부분의 일부 코드입니다 웹 크롤링 api를 사용하여 시장정보를 가져와 mapper의 두가지 기능(delete와 insert)를 사용하고 있는데 제가 이해한 바로는 스케쥴링을 통해 api를 호출할 때마다 delete쿼리를 실행하고 다시 insert쿼리를 실행시키는 방식인데 정말 이방법 밖에 없는지 궁금합니다 또한 mapper interface에서 정의한 기능 여러개가 service interface에서 하나의 기능으로 합쳐지는 코드로 작성하는 방법에 대한 의견도 궁금합니다 많이 가르쳐주시면 감사하겠습니다

1@Scheduled(cron = "0 0 0 * * ?") // 매일 자정에 실행
2//    @Scheduled(fixedRate = 60000) // 매분마다 실행
3    public void getMarketInfo() throws Exception {
4
5        log.info(this.getClass().getName() + ".getMarket Start!");
6        StringBuilder urlBuilder = new StringBuilder("http://openapi.seoul.go.kr:8088"); /*URL*/
7        urlBuilder.append(설정항목들)
8
9        URL url = new URL(urlBuilder.toString());
10        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
11        conn.setRequestMethod("GET");
12        conn.setRequestProperty("Content-type", "application/xml");
13        System.out.println("Response code: " + conn.getResponseCode()); /* 연결 자체에 대한 확인이 필요하므로 추가합니다.*/
14        BufferedReader rd;
15
16        // 서비스코드가 정상이면 200~300사이의 숫자가 나옵니다.
17        if(conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
18            rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
19        } else {
20            rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
21        }
22        StringBuilder sb = new StringBuilder();
23        String line;
24        while ((line = rd.readLine()) != null) {
25            sb.append(line);
26        }
27        rd.close();
28        conn.disconnect();
29        System.out.println(sb.toString());
30
31        Map<String, Object> json = new ObjectMapper().readValue(sb.toString(), LinkedHashMap.class);
32
33        Map<String, Object> rMap = (Map<String, Object>) json.get("ListTraditionalMarket");
34
35        List<Map<String, Object>> list = (List<Map<String, Object>>) rMap.get("row");
36
37        marketMapper.deleteMarket();
38
39        for(Map<String, Object> market : list) {
40            MarketDTO rDTO = new MarketDTO();
41
42            String name = (String) market.get("ITEM_NM");
43            String addr = (String) market.get("ITEM_ADDR");
44
45            log.info("name : " + name);
46            log.info("addr : " + addr);
47
48            rDTO.setName(name);
49            rDTO.setAddr(addr);
50
51            marketMapper.insertMarket(rDTO);
52        }
53
54        log.info(this.getClass().getName() + ".getMarket End!");
55    }
이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 0

답변이 없을 때 보이는 아이콘

첫 답변을 기다리고 있어요.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2023년 11월 10일

이 코드는 매일 자정에 외부 API를 통해 시장 정보를 가져와 데이터베이스를 업데이트하는 것으로 보입니다. 먼저, delete 쿼리를 실행하여 기존의 데이터를 삭제한 다음, 새로운 정보를 insert하는 방식을 사용하고 있습니다. 하지만 이 방법은 항상 최신 데이터만 유지하고 싶을 때 유용합니다. 이전의 데이터가 중요하지 않거나 변동사항이 클 때 효과적인 접근방식입니다. 하지만 모든 상황에서 이방법이 범용적으로 효과적인 것은 아닙니다. 예를 들어, 과거 데이터가 필요할 경우나 분석을 위해 히스토리가 필요한 경우에는 적합하지 않습니다. Mapper interface에서 정의된 여러 함수들을 service layer에서 하나의 기능으로 합치는 것은 일반적인 설계 패턴입니다. 이렇게 하는 이유는 업무 로직을 최대한 Service Layer에 집중시켜 코드의 가독성과 유지보수성을 높이기 위함입니다. 예를 들어, '주문'이라는 하나의 비즈니스 로직 처리를 위해 주문 생성(Create Order), 재고 감소(Decrease Stock), 배송 시작(Start Delivery) 등 여러 DB 작업이 필요할 수 있는데, 이런 여러 작업들을 서비스 레이어에서 하나의 함수(예: processOrder())로 묶어서 처리하는 것입니다. 이렇게 하면 비즈니스 로직의 흐름을 더 쉽게 파악할 수 있고 코드의 유지보수성도 개선할 수 있습니다. 마지막으로, 주어진 코드에서는 모든 market 정보를 한 번에 쿼리하여 DB에 저장하고 있습니다. 만약 가져오는 데이터가 많아질 경우 메모리 이슈가 발생할 가능성이 있으므로, 페이징 처리나 일부 데이터만큼만 쿼리하여 처리하는 등의 방법도 고려해 볼 만합니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!