백엔드 개발하며 작성한/Spring

JAP Query로 특정 칼럼의 count 쿼리문 실행하기

뭉지(moonz) 2021. 11. 12. 22:06
반응형

상황

JAP Query문으로 특정 칼럼의 count를 조회해야하는 상황

 

해결

여러 글을 구글링해보고 다음과 같이 작성하였다. stackoverflow의 글을 첨부한다.

보통 조건값으로 조회, 합계된 값 조회 등을 쿼리하는 것과 같이 복잡한 쿼리문을 수행하고자 할 때 이 방식을 사용하는 것 같다. 이외에도 2가지 정도의 방법이 더 있었다.  (참고1, 참고2)

 

위 글 뿐만 아니라 많은 곳에서 List<Object> 로 값을 받도록 작성되어 있다. (여기서 꽤 애를 먹었다..)

내가 받는 결과값은 2차원이므로 List<Object[]>, List<List>와 같이 해주어야 한다.

(본인은 전자로 하였다.)

public interface UserRepository extends JpaRepository<User, Long> {
    // select를 통해 여러개의 값을 받는다면 List<Object[]> 타입으로 받은 뒤 형변환해서 사용
    @Query("SELECT " +
            "u.nowEmotion, count(u) " +
            "FROM User u " +
            "GROUP BY u.nowEmotion"
    )
    List<Object[]> countEmotions();
}

아래의 문제와 맞물리면서 Object[]로 2차원 select값을 받고, 이를 형변환해주어 값을 얻어내는 것 까지 꽤 많은 삽질을 했다..

 

 

문제

Controller를 통해 반환되는 값은 [[1, 21], [0, 11], [2, 221]] 와 같이 출력되었지만 (url로 접근),

특정 값에 접근하려 하면

[[Ljava.lang.Object;@4ac6f8ef, [Ljava.lang.Object;@3e827af6, [Ljava.lang.Object;@694d6186]

와 같이 주소값이 출력되는 문제

 

해결

Object[]로 받았기 때문에 적절한 형변환을 해주어야 한다.

String으로 변환하기 위해 Object를 String으로 형변환하는 String.valueOf()를,

Integer로 변환하기 위해 먼저 Object를 String으로 변환해준 후, String을 Integer로 변환하는 Integer.parseInt()를 사용하였다.

 

코드

[controller/UserRestController.java]

@GetMapping("/emotion")
public HashMap<String,Integer> emotionCount() {

   /*  2. 사용자의 emotion 합계 조회  */
   HashMap<String,Integer> emotionMap = userService.findEmotionCount();    // {0: 15, 1: 19, 2: 4}

   return emotionMap;
}

 

[service/userService.java]

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
	public  HashMap<String,Integer> findEmotionCount() {

        List<Object[]> emotionQuery= userRepository.countEmotions();
        HashMap<String,Integer> emotionMap = new HashMap<String, Integer>();

        // Object[] 이므로 형변환 해줘야한다.
        for (Object[] o : emotionQuery) {
            String emotion = String.valueOf( o[0]);
            int count = Integer.parseInt(o[1].toString());
            emotionMap.put(emotion, count);
        }
        System.out.println(emotionMap.entrySet());
        return emotionMap;
    }
}

이후를 위해 딕셔너리 형태로 반환해두고자 형변환된 요소들을 HashMap<String, Integer> 인 emotionMap 에 추가하였다.

 

 

결과

api 요청 결과
print 결과

 

 

참고

https://github.com/BananMoon/healing4u-mobileWeb/pull/1

 

Repository_emotion 값에 대한 count 구하기 by BananMoon · Pull Request #1 · BananMoon/healing4u-mobileWeb

POINT UserRepository에서 @Query()를 통해 select문을 작성하여 요청하는 메서드 countEmotions 선언 컨트롤러에서 서비스 계층 호출 ➡️ 서비스 계층에서 Repository계층의 메서드 countEmotions 호출 select를 통해

github.com

 

반응형