Baeg-won
좋았다면 추억이고 나빴다면 경험이다.
Baeg-won
전체 방문자
오늘
어제
  • 분류 전체보기
    • 🍃 Spring, Spring Boot
      • 스프링 프레임워크 기초
      • 스프링 핵심 원리 - 기본편
      • 자바 ORM 표준 JPA 프로그래밍 - 기본편
      • 스프링 MVC
      • 실전! 스프링 부트와 JPA 활용1 - 웹 애플리..
    • 🥑 Web Technoloy
    • 🚗 Backend Toy Project
      • 스프링 부트 게시판
      • Photogram
      • Baeg-won Clothing Gallery
    • 🥇 Problem Solving
      • Breadth-First Search
      • Depth-First Search
      • Backtracking
      • Simulation
      • Two-pointer
      • Binary Search
      • Greedy
      • Dynamic Programming
      • Minimum Spanning Tree
      • Dijkstra
      • Floyd warshall
    • ☕ Java
      • 명품 자바 에센셜
      • Applications
    • 🍦 JavaScript
      • JavaScript 기초
    • 🐧 Linux
      • 이것이 리눅스다(CentOS 8)
    • 📟 Database
      • 혼자 공부하는 SQL
    • 🧬 Data Structure
    • 🎬 HTML
    • 🎤 Tech Interview
    • 📌 etc
      • Unity 2D Raising Jelly Game
      • C++
      • 영어 쉐도잉

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Baeg-won

좋았다면 추억이고 나빴다면 경험이다.

🥑 Web Technoloy

JPQL과 QueryDSL

2023. 6. 4. 15:26

  • JPA와 같은 ORM을 사용하면 시스템이 커질수록 쿼리가 복잡해지는 문제가 발생합니다.
  • JPQL과 QueryDSL은 이러한 문제를 해결하기 위해 고안된 기법입니다.

💡 JPQL

  • JPQL은 JPA의 일부로 Query를 Table이 아닌 객체(=엔티티) 기준으로 작성하는 객체지향 쿼리 언어라고 정의할 수 있습니다.
  • JPQL은 객체를 기준으로 모든 것이 움직이기 때문에 개발할 때, Table에 매핑되는 객체가 반드시 존재해야하며 검색할 때도 Table이 아닌 객체를 대상으로 검색해야 합니다.
  • 전반적인 특징에 대해 간단히 다시 정리한다면 다음과 같습니다.
1. SQL을 추상화한 JPA의 객체지향 쿼리
2. Table이 아닌 Entity를 대상으로 개발
3. Entity와 속성은 대소문자를 구분 (PERSON <> person)
4. 별칭(alias) 사용 필수
  • JPQL을 실제 구현하는 방식으로는 크게 두 가지 방식이 있습니다.

 

✔ EntityManager 활용

@Autowired
EntityManager em;

Person person = new Person();
Person.setFirstName("Sungkwon");
Person.setLastName("Cho");
userRepository.save(person);	// JPA 문법 (save == INSERT문)

TypedQuery<User> tq = em.createQuery("select p from Person p where p.FirstName = :firstName and p.LastName = :lastName", Person.class);
tq.setParameter("firstName", "Sungkwon");
tq.setParameter("lastName", "Cho");

List<Person> personList = tq.getResultList();
LOGGER.info("firstName: " + personList.get(0).getFirstName());

 

✔ Repository Interface 활용

public interface PersonRepository extends JpaRepository<Person, Long>{

   /* 변수 바인딩 시, ?시퀀스 사용하는 경우 */
   @Query("select p from Person p where p.firstName = ?1 and p.lastName = ?2")
   Person findPerson(String firstName, String lastName);
   
   /* 변수 바인딩 시, :이름 사용하는 경우 */
   @Query("select p from Person p where p.firstName = :firstName and p.lastName = :lastName")
   Person findPerson2(@Param("firstName") String firstName, @Param("lastName") String lastName);
}
  • 위 두 가지 방식은 구현하는 방법에 있어서 확연한 차이가 있습니다.
  • 하지만, 결과적으로 이 둘의 공통점이자 문제점으로는 여전히 쿼리를 String 형태로 작성하고 있다는 점입니다.
  • JPQL의 문제점에 대해 정리하면 다음과 같습니다.
1. JPQL은 문자열(=String) 형태이기 때문에 개발자 의존적 형태
2. Compile 단계에서 Type-Check가 불가능
3. RunTime 단계에서 오류 발견 가능 (장애 risk 상승)

💡 QueryDSL

  • 앞서 언급한 JPQL의 문제점을 보완을 위해 고안된 것이 QueryDSL이라고 볼 수 있습니다.
  • QueryDSL은 정적 타입을 이용해서 SQL, JPQL을 코드로 작성할 수 있도록 도와주는 오픈소스 빌더 API를 말합니다.
  • QueryDSL을 사용하는 목적은 뚜렷합니다.
  • 기존 방식(Mybatis, JPQL, etc..)은 모두 문자열(=String) 형태로 쿼리가 작성되었고, 이로 인해 Compile 단계에서 Type-Check가 불가능 했습니다.
  • 이러한 risk를 줄이기 위해 QueryDSL이 등장했고, 이를 통해 Compile 단계에서 Type-check가 가능해진 것입니다.
  • 이를 예시를 통해 확인해보겠습니다.
@PersistenceContext
EntityManager em;

public List<Person> selectPersonByNm(String firstNm, String lastNm){
    JPAQueryFactory jqf = new JPAQueryFactory(em);
    QPerson person = QPerson.person;

    List<Person> personList = jpf
                        .selectFrom(person)
                        .where(person.firstName.eq(firstNm)
                        .and(person.lastName.eq(lastNm))
                        .fetch();

    return personList;
}
  • 위 코드는 QueryDSL를 활용하여 모든 쿼리에 대한 내용을 함수 형태로 작성한 코드입니다.
  • 이렇게 엔티티(객체) + 함수 형태로 구성된 QueryDSL을 통해 구현된 코드는 오류가 존재할 시, Compile 단계에서 바로 확인 가능하며, 이에 따른 후속 조치가 가능하기 때문에 그만큼 risk가 줄어들게 되는 것입니다.
  • 몰론 코드 라인수가 길어진다는 유일한 단점이 존재하긴 하지만 코드의 수가 조금 길어지더라도 가독성이 저하될만큼 코드가 복잡하거나 하지 않기 때문에 큰 단점이라 생각되진 않습니다.
  • QueryDSL의 특징을 다시 한 번 정리하자면 다음과 같습니다.
1. 문자가 아닌 코드로 작성
2. Compile 단계에서 문법 오류 확인 가능
3. 코드 자동 완성 기능 활용 가능
4. 동적 쿼리 구현 가능

📌 References

  • https://velog.io/@cho876/JPQL-vs-query-DSL
저작자표시

'🥑 Web Technoloy' 카테고리의 다른 글

CSRF란?  (0) 2023.06.11
URI와 URL  (0) 2023.06.06
JPA와 Hibernate 그리고 Spring Data JPA  (0) 2023.06.04
Lombok이란?  (1) 2023.06.04
Spring AOP(Aspect Oriented Programming)  (0) 2023.06.03
    '🥑 Web Technoloy' 카테고리의 다른 글
    • CSRF란?
    • URI와 URL
    • JPA와 Hibernate 그리고 Spring Data JPA
    • Lombok이란?
    Baeg-won
    Baeg-won

    티스토리툴바