inblog logo
|
LifeLog, DevLog
    JPA

    JPQL 기본

    아주 간략하게만
    KYJTHEYJ's avatar
    KYJTHEYJ
    Jan 02, 2026
    JPQL 기본
    Contents
    JPQL예시기본 문법

    JPQL

    JPA용 쿼리 언어로 SQL과 비슷하나 Entity를 대상으로 하는 점이 다르다

    문자열로 쿼리가 작성되므로 컴파일 에러로 검출 할 수가 없다

    너무나 복잡한 수가 필요시 nativeQuery 값을 조절하여 순수 SQL 사용이 가능하다

    일반적인 복잡한 예시를 가져올 때 사용한다
    (어떤 조건이 몇 이상이고 이름이 어떤 것이고, 기간은 일주일 이내 검색된 데이터 색출)
    (이런 경우는 일반 JPA 메서드 쿼리 기능으로는 가져오는 것이 어려움)

    예시

    멤버 테이블과 팀에 대한 테이블이 있고
    팀 속에 멤버가 포함되는 구조의 테이블이 있다고 가정

    이 중에 나이가 20 이상인 전체 팀원 정보와 그들이 속한 팀 정보를 검색하려한다

    일반 SQL 시

    SELECT 
        m.id, 
        m.name, 
        m.age, 
        t.name as team_name
    FROM members m
    LEFT JOIN teams t ON m.team_id = t.id
    WHERE m.age >= 20;

    JPQL 활용 시

    // Repository 부분에 따로 선언
    @Query("""
        SELECT m 
        FROM Member m 
        LEFT JOIN m.team t
        WHERE m.age >= 20
    """)
    List<Member> findOlderMembers();

    차이점

    Entity를 대상으로 하고 있어
    연관관계만 표시하지 따로 ON 조건인 연관되는 필드를 명시하지 않음

    기본 문법

    SELECT

    • SQL

    --1) 
    SELECT * FROM members;
    
    --2) 
    SELECT name FROM members;
    • JPQL

    //1)
    @Query("SELECT m FROM Member m")
    List<Member> findAll();
    
    //2)
    @Query("SELECT m.name FROM Member m")
    List<String> findAllName();
    
    // DTO 활용 조회
    @Query("""
           SELECT new com.example.dto.MemberDto(m.name, m.age)
           FROM Member m
    """)
    List<MemberDto> findAllDto();

    WHERE

    SQL 과 사용법 자체는 다르지 않지만 파라미터 대입은 다름

    @Query 절의 파라미터 대입의 이름과 같게 @Param 선언이 필요함

    • JPQL

    // 파라미터의 이름과 일치하도록 @Param에 선언하여 사용
    @Query("SELECT m FROM Member m WHERE m.name = :name")
    List<Member> findByName(@Param("name") String name);

    JOIN

    Entity의 연관관계를 활용하므로 따로 컬럼을 기재하지 않음
    (다만 JPA 2.1 이상부터는 ON 절 사용 가능함)
    따로 FK에 대해 어떠한 관계도 없다면 사용이 불가함
    (일반적인 상황에서만, JPA 2.1 부터 ON 절 기재가 가능해서
    괜찮긴 하나 Fetch Join이 안됨)
    (N+1 문제 발생 여지)

    이러한 경우엔 nativeQuery = true 로 사용하던지
    ConstraintMode 를 조절해서 NO_CONSTRAINT 로 사용해야함

    • JPQL

    // 기본 JOIN
    @Query("SELECT m FROM Member m JOIN m.team t WHERE t.name = :teamName")
    List<Member> findByTeamName(@Param("teamName") String teamName);
    
    // Fetch Join
    @Query("SELECT m FROM Member m JOIN FETCH m.team")
    List<Member> findAllWithTeam();
    
    // 실행되는 SQL:
    // SELECT m.*, t.*
    // FROM members m
    // INNER JOIN teams t ON m.team_id = t.id;
    
    // LEFT JOIN
    @Query("SELECT m FROM Member m LEFT JOIN FETCH m.team")
    List<Member> findAllWithTeamLeftJoin();
    
    // ========== JPA 2.1+ ON 절 지원 ==========
    @Query("""
        SELECT m 
        FROM Member m 
        LEFT JOIN Team t ON m.teamId = t.id
        WHERE t.name = :teamName
    """)
    List<Member> findByTeamNameOn(@Param("teamName") String teamName);
    
    // 실행 SQL:
    // SELECT m.* 
    // FROM members m 
    // LEFT JOIN teams t ON m.team_id = t.id 
    // WHERE t.name = ?
    
    // 여러개 Fetch JOIN
    @Query("""
        SELECT DISTINCT m 
        FROM Member m 
        LEFT JOIN FETCH m.team 
        LEFT JOIN FETCH m.orders
    """)
    List<Member> findAllWithTeamAndOrders();

    nativeQuery 를 사용 할 때 주의 할 점

    사용 하기 전에 영속성 컨텍스트를 사용하는 부분이 있었다면 flush 해야한다
    nativeQuery 를 사용할 때와 다르게 자동으로 flush 처리해주지 않기 때문에!

    Share article
    Contents
    JPQL예시기본 문법

    LifeLog, DevLog - https://github.com/KYJTHEYJ

    RSS·Powered by Inblog