CODING/스파르타 내일배움캠프 TIL

53_푸드 파이트 대회_Spring 플러스 주차 개인 과제 트러블슈팅_25.3.11(화)

codingTrip 2025. 3. 11. 22:58

코드카타

51) 푸드 파이트 대회

나의 풀이

import java.util.*;

class Solution {
        public String solution(int[] food) {
            String answer = "";
            List<Integer> numbers = new ArrayList<>();
            for (int i = 1; i < food.length; i++) {
                if (food[i]/2 < 1){
                    continue;
                }
                for (int j = 0; j < food[i]/2; j++) {
                    numbers.add(i);
                }
            }

            for (int i = numbers.size()-1; i >= 0; i--) {
                numbers.add(numbers.get(i));
            }

            numbers.add(numbers.size()/2, 0);

            StringBuilder sb = new StringBuilder();
            for (Integer number : numbers) {
                sb.append(number);
            }
            answer = sb.toString();
            return answer;
        }
}

for문을 또 2개 만들었다...

사실 이 방법이 내키지는 않았지만 그 이상의 생각이 어려웠다.

그래도 나름 StringBuilder를 시도했다는 것에 만족하고자 한다.

 

다른 분들의 풀이

class Solution {
    public String solution(int[] food) {
        String answer = "0";

        for (int i = food.length - 1; i > 0; i--) {
            for (int j = 0; j < food[i] / 2; j++) {
                answer = i + answer + i; 
            }
        }

        return answer;
    }
}

출처:https://school.programmers.co.kr/learn/courses/30/lessons/134240/solution_groups?language=java

 


2025.03.11(화)

Spring 플러스 주차 개인 과제 트러블슈팅

필수

Lv 1-3. 코드 개선 퀴즈 - JPA 이해

Caused by: org.hibernate.query.SemanticException: Cannot compare left expression of type 'java.time.LocalDateTime' with right expression of type 'java.lang.Object'

Repository JPQL 쿼리 부분에서 발생했다.

처음에는 원인을 찾기 어려웠으나,

WHERE 조건의 범위를 주석 처리하면서 그 원인을 찾았다.

 

바로 DATE_ADD(DATE(:endDate),1)에서 발생했다.

DATE_ADD 메서드를 사용하고자 했던 이유는

t.modifiedAt < DATE(:endDate)

위의 부분에서 입력한 날짜에 1일을 더해야 조건이 부합되기 때문이었다.

ex) endDate=2025-03-11 -> 1일 더함 -> t.modifiedAt < 2025-03-12 -> 2025-03-11까지 모두 조회 가능함

 

해결 방법은 Service에서 1일을 더해주고, 이를 Repository 매개변수로 넘겨주었다.

아래와 같이 하니 내가 의도한대로 조건이 잘 작동되는 것을 알 수 있었다.

endDate = endDate!= null ? endDate.plusDays(1) : null;
Page<Todo> todos = todoRepository.findAllByOrderByModifiedAtDesc(pageable, weather, startDate, endDate);

endDate가 null일 경우에 대해서는 삼항 연산자로 처리했다.

null이 아닌 경우에 1일을 더하고 null인 경우에는 null 처리했다.


2025-03-11T18:17:08.501+09:00  WARN 9249 --- [expert] [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDateTime'; Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam java.time.LocalDateTime] for value [2025-03-11]]

Controller에서 파라미터에 대해 LocalDateTime으로 설정했었는데, 이것이 문제가 되었다.

@RequestParam(required = false) LocalDate startDate,
@RequestParam(required = false) LocalDate endDate,

위와 같이 LocalDate로 변경하니 해결되었다.


Caused by: org.hibernate.query.QueryArgumentException: Argument [2025-03-11] of type [java.time.LocalDate] did not match parameter type [java.time.LocalDateTime (n/a)]

Repository에서 :startDate, :endDate 파라미터에 DATE() 메서드를 사용하니 해결이 되었다.

 

완성된 코드는 아래와 같다.

@Query("SELECT t FROM Todo t LEFT JOIN FETCH t.user u " +
            "WHERE (coalesce(:weather, NULL) IS NULL OR t.weather = :weather) " +
            "AND CASE WHEN :startDate IS NOT NULL AND :endDate IS NOT NULL " +
            "THEN (t.modifiedAt >= DATE(:startDate) AND t.modifiedAt < DATE(:endDate)) " +
            "WHEN :startDate is null AND :endDate is not null " +
            "THEN (t.modifiedAt < DATE(:endDate)) " +
            "WHEN :startDate is not null AND :endDate is null " +
            "THEN (t.modifiedAt >= DATE(:startDate)) " +
            "WHEN :startDate is null AND :endDate is null " +
            "THEN (1=1) " +
            "END " +
            "ORDER BY t.modifiedAt DESC")
    Page<Todo> findAllByOrderByModifiedAtDesc(Pageable pageable, String weather, LocalDate startDate, LocalDate endDate);

CASE문을 사용하고 싶어서 사용해보았다.

시작일, 종료일을 각각 입력함에 따라 다양한 조건을 발생할 수 있도록 쿼리를 작성했다.