hanker

Spring - JPQL(Java Persistence Query Language) 완벽 정리 본문

SPRING

Spring - JPQL(Java Persistence Query Language) 완벽 정리

hanker 2024. 10. 24. 00:56
반응형

JPQL(Java Persistence Query Language)
 
 
 

개발된 이유

JPA(Java Persistence API)가 2006년에 도입되면서 함께 등장했는데, 
기존 SQL의 테이블 중심적인 쿼리 작성 방식에서 객체 중심적인 쿼리 작성을 가능하게 하기 위해 개발

 
 

JPQL이란?

객체지향 쿼리 언어로, 엔티티 객체를 대상으로 쿼리를 작성하는 언어이며, SQL과 비슷한 문법을 가지고 있지만, 테이블이 아닌 엔티티 객체를 대상으로 쿼리를 작성한다. 작성한 JPQL을 JPA가 SQL로 변환해서 데이터베이스에서 실행
  
 

주요기능은..

 
 

- 엔티티 객체를 대상으로 하는 검색 기능

private final EntityManager em;


public void testJPQL(){
    String jpqlA = "SELECT u FROM User u WHERE u.userName = :name";
    String jpqlB = "SELECT u FROM User u WHERE u.userName = :name AND u.userId = :id";

    List<User> userA = em.createQuery(jpqlA, User.class)
            .setParameter("name", "Han-ker")
            .getResultList();

    List<User> userB = em.createQuery(jpqlB, User.class)
            .setParameter("name", "Han-ker")
            .setParameter("id", "hanker")
            .getResultList();

    System.out.println("userA");
    System.out.println(userA);

    System.out.println("userB");
    System.out.println(userB);
}

테이블에는 underscore 방식으로 컬럼명이 지정되어있는데, 해당 Entity에 등록된 객체로 Database 조회가 가능하다.

 

반응형


 
- 페이징 처리

private final EntityManager em;


public void testJPQL(){
    String jpqlA = "SELECT m FROM User m ORDER BY m.userName DESC";

    // 전체 건수 조회와 함께 사용
    String countJpql = "SELECT COUNT(m) FROM User m";
    long totalCount = em.createQuery(countJpql, Long.class)
            .getSingleResult();

    // 페이지 계산 예시
    int page = 1;
    int size = 10;
    List<User> user = em.createQuery(jpqlA, User.class)
            .setFirstResult((page-1) * size)
            .setMaxResults(size)
            .getResultList();

    System.out.println("totalCount: " + totalCount);
    System.out.println("page: " + page);
    System.out.println("size: " + size);
    System.out.println("user: " + user);
}

결과

 
 
- DTO 조회

private final EntityManager em;


public void testJPQL(){
    String jpql3 = "SELECT new User(m.userId, m.userName, m.userSn, m.password)" +
            "FROM User m";

    List<User> list = em.createQuery(jpql3)
                        .getResultList();

    System.out.println("list = " + list);
}

결과

 
 
- 집계함수, GROUP BY / HAVING, JOIN

private final EntityManager em;

public void testJPQL(){
    String jpql = "SELECT new com.hanker.exampleboot.api.model.TeamStatDTO(t.teamName, COUNT(m), AVG(m.age)) " +
            "FROM User m " +
            "JOIN m.team t " +
            "WHERE m.age >= :minAge " +
            "GROUP BY t.teamName " +
            "HAVING COUNT(m) >= 2 " +
            "ORDER BY t.teamName";

    List<TeamStatDTO> list = em.createQuery(jpql, TeamStatDTO.class)
            .setParameter("minAge", 20)
            .setFirstResult(0)
            .setMaxResults(5)
            .getResultList();

    System.out.println("list = " + list);
}

결과

 
 
 

마치며

 

- 엔티티의 필드명이 변경될 경우 JPQL도 수정해야 함
- 동적 쿼리 작성 시 String 연결보다는 Criteria나 QueryDSL 사용 권장
- 복잡한 쿼리의 경우 native SQL을 사용하는 것이 더 효율적일 수 있음
- 대소문자를 구분하여 작성해야 함 (엔티티와 속성은 대소문자 구분)

 

반응형