본문 바로가기
Framework and Tool/JPA

JPA - 객체지향 쿼리 언어 - JPQL Paging, 집합, 정렬

by ocwokocw 2021. 7. 29.

- 참조: 자바 ORM 표준 JPA 프로그래밍

- PostgreSQL limit offset: https://www.postgresql.org/docs/12/queries-limit.html

- 페이징 API

다양한 데이터베이스에서 개발해본 사람이라면 알겠지만 페이징 SQL 작성은 데이터베이스마다 구문을 다르게 작성해주어야하고 반복되는 일이 많아 번거롭다.

 

JPA 는 페이징에 대한 API 를 제공한다.

  • setFirstResult(int startPosition): 조회 시작 위치(0부터 시작)
  • setMaxResults(int maxResult): 조회할 데이터 수

 

String jpql = "select m from Member m order by m.name asc";

List<Member> members = em.createQuery(jpql, Member.class)
	.setFirstResult(10)
	.setMaxResults(20)
	.getResultList();

members.forEach(System.out::println);

 

위의 코드에서 setFirstResult 함수에 startPosition 10을 지정했으므로 11부터 조회한다. 그리고 20 개를 조회 하므로 11 ~ 30 개의 데이터를 조회한다.

 

여담이지만 Paging SQL 을 작성할때에는 order by 절을 명시해줘야 paging 이 제대로 동작한다. 데이터베이스 제품 중 PostgreSQL 에서 페이징 구문인 limit offset 에 관한 문서에를 보면 아래와 같이 명시가 되어있다.

 

When using LIMIT, it is important to use an ORDER BY clause that constrains the result rows into a unique order. Otherwise you will get an unpredictable subset of the query's rows. You might be asking for the tenth through twentieth rows, but tenth through twentieth in what ordering? The ordering is unknown, unless you specified ORDER BY.

 

대충 Order by 를 사용해줘야 신뢰할 수 있는 부분 결과(subset)를 얻을 수 있다는 얘기이다. 여하튼 코드를 실행하여 수행되는 SQL 을 보면 limit offset 을 사용하는 아래와 같은 형태로 나온다. 

 

Hibernate: 
    /* select
        m 
    from
        Member m 
    order by
        m.name asc */ select
            member0_.member_id as member_i1_4_,
            member0_.insert_datetime as insert_d2_4_,
            member0_.update_datetime as update_d3_4_,
            member0_.city as city4_4_,
            member0_.street as street5_4_,
            member0_.zipcode as zipcode6_4_,
            member0_.name as name7_4_ 
        from
            member member0_ 
        order by
            member0_.name asc limit ? offset ?

 

중요한것은 JPQL 에서 데이터베이스의 특징과는 관련없이 API 에 인자를 넘겨주면 알아서 SQL 을 생성해준다는것이다. 만약 데이터베이스가 변경되어 Dialect 를 변경해주면 Mybatis 같은 경우 SQL 을 모두 변경해주는 작업을 해주어야 하겠지만 JPA 는 그렇지 않다.


- 집합과 정렬

집합과 정렬은 이 글의 제목에는 언급했지만 기존 SQL 과 차이점이 없어서 작성할 내용은 없다. 

댓글