본문 바로가기

백/spring boot

JPA findBy~In 쿼리

findByIdIn(List<Long> ids)

이런식으로 입력받은 ids 리스트에 해당하는 spot들을 찾아야 했다.

 

이때 ids는 각 이미지 별로 어떤 포토스팟에 해당하는지를 나타내는 용도이기에 중복된 id 값들이 들어갈 확률이 아주 높다.

예를 들어 1,1,3,2,4,2,....

 

하지만 In절비교 연산자 (=) 와 논리 연산자 (OR) 을 결합한 연산자로, 인자 리스트 (ids)에 중복된 값이 들어오면 자동으로 중복값을 제거를 해버린다.

예를 들어 1,1,3,2,4,2 이렇게 들어왔다면 1,3,2,4만 남는 것이다. 

findByIdIn(1L,1L,3L,2L,4L,2L)
findByIdIn(1L,3L,2L,4L)

따라서 이렇게 중복 제거된 조건이 사용된다!

 

더불어 중복제거 뿐만 아니라 순서보장도 하지 못한다. 따라서 중복이 필요하거나 순서 보장이 필요할 때는 별다른 조치를 해야 한다.

public List<Spot> findSpotsById(List<Long> spotIds){
		//중복 제거된 spot 리스트 가져오기
        List<Spot> spotNoOverlap = spotRepository.findByIdIn(spotIds);

        //key:id value:spot으로 하는 map 생성
        Map<Long, Spot> map = spotNoOverlap.stream()
                .collect(Collectors.toMap(Spot::getId, spot -> spot));
		
        //spotIds 리스트 돌며 해당하는 id의 spot 모아 리스트 생성
        return spotIds.stream()
                .map(spotId -> {
                    Spot spot = map.get(spotId);

                    if(spot==null){
                        throw new IllegalArgumentException(spotId + "id의 스팟은 존재하지 않습니다.");
                    }
                    return spot;
                })
                .toList();
    }