[Java / Spring / JPA] Native Query와 QLRM 라이브러리

2023. 1. 25. 08:18·Framework & Library/Spring
JPA(Java persistence API)를 사용하여 서비스를 구현하다 보면 JPA에서 제공하는 기능만으로는 조회가 불가능한 경우가 존재한다.
대표적으로 엔티티 객체를 그대로 조회하는 것이 아닌 DTO에 맞춰서 조회하는 경우이다.

 

[ 예시 / 인스타그램 클론코딩 중 구독 정보 조회 커리 ]

SELECT u.id, u.username, u.profileImageUrl, 
if((SELECT 1 FROM subscribe 
WHERE fromUserId = 1 AND toUserId = u.id),1,0) subscribeState,
if((1=u.id),1,0) equalUserState
FROM user u INNER JOIN subscribe s
ON u.id = s.toUserId
WHERE s.fromUserId = 2;

이런식으로 필요한 데이터를 쿼리로 작성하고 스프링에 대입해주면 된다.

여러가지 방법이 존재하지만 손쉽게 할 수 있는 QLRM 라이브러리를 사용해보려고 한다.

 

[ build.gradle ]

implementation group: 'org.qlrm', name: 'qlrm', version: '3.0.4'

 

[ SubscribeSerive.java ]

@RequiredArgsConstructor
@Service
public class SubscribeService {

   private final SubscribeRepository subscribeRepository;
   private final EntityManager em; // Repository는 EntityManager를 구현해서 만들어져 있는 구현체

   @Transactional(readOnly = true)
   public List<SubscribeDto> 구독리스트(int principalId, int pageUserId) {
      // 쿼리 준비
      StringBuffer sb = new StringBuffer();
      sb.append("SELECT u.id, u.username, u.profileImageUrl, ");
      sb.append("if ((SELECT 1 FROM subscribe WHERE fromUserId = ? AND toUserId = u.id), 1, 0) subscribeState, "); // 물음표 principalId
      sb.append("if ((?=u.id), 1, 0) equalUserState "); // 물음표 principalId
      sb.append("FROM user u INNER JOIN subscribe s ");
      sb.append("ON u.id = s.toUserId ");
      sb.append("WHERE s.fromUserId = ?"); // 물음표 pageUserId

      // 쿼리 완성
      Query query = em.createNativeQuery(sb.toString())
         .setParameter(1, principalId)
         .setParameter(2, principalId)
         .setParameter(3, pageUserId);

      // 쿼리 실행 (qlrm 라이브러리 필요 = Dto에 DB결과를 매핑하기 위해서)
      JpaResultMapper result = new JpaResultMapper();
      List<SubscribeDto> subscribeDtos = result.list(query, SubscribeDto.class);
      return subscribeDtos;
   }
}
  • 해당 쿼리가 리턴하는 값이 Subscribe 타입이 아니기 때문에 사용하려는 Service에서 직접 Native Query를 작성해주어야한다.
    -> 그러기 위해 EntityManager를 DI 해준다.
  • 쿼리 준비를 위한 StringBuffer를 만들고 필요한 파라미터를 변수 바인딩 해준다.
    -> 변수를 ?로 바인딩하고, em.createNativeQuery를 이용하여 각각 변수를 바인딩 해줄 수 있다.
  • 해당 쿼리를 실행해주기 위해 JpaResultMapper를 사용해준다
    -> QLRM이 지원해주는 메소드이다.

 

해당 코드가 잘 작동하면 아래와 같이 데이터가 불러와진다.

 

저작자표시 (새창열림)
'Framework & Library/Spring' 카테고리의 다른 글
  • [Java / Spring] JSP -> Thymeleaf(타임리프) 변경
  • [Spring] Spring Security PrincipalDetails 와 mustache template
  • [Java / Spring / JPA] 맵핑 어노테이션 @Entity, @Table, @Column, @Id
  • [Java / Spring] Spring Security란?
마볼링
마볼링
개발과 게임에 관한 내용을 읽기 쉽게 정리합니다.
  • 마볼링
    게임을 좋아하는 개발자의 블로그
    마볼링
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Project
        • LOATODO
        • 인스타그램 클론코딩(중단)
      • Language
        • Java
        • PHP
        • Javascript
      • Framework & Library
        • Spring
        • Vue
      • Computer Science
        • Web
        • Linux
      • CodingTest
        • Algorithm
        • Kotlin으로 푼 코딩 테스트
        • Java로 푼 코딩 테스트
        • Sorting & Thinking
        • BFS
      • 책&강의 정리
      • 정보처리기사
      • 개인
        • 팰월드(PALWORLD)
        • 마인크래프트
  • 블로그 메뉴

    • 링크

      • GitHub
      • Threads
    • 공지사항

    • 인기 글

    • 태그

      프로그래머스
      JPA
      코딩테스트
      java
      운영체제
      LoaTodo
      CS
      springboot
      티스토리챌린지
      아크 서바이벌
      codingtest
      jsp
      php
      로아투두
      네트워크
      Spring
      오블완
      error
      이터널 모드
      Database
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.1
    마볼링
    [Java / Spring / JPA] Native Query와 QLRM 라이브러리
    상단으로

    티스토리툴바