JPQL - JPQL 기본(4)
"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."
www.inflearn.com/course/ORM-JPA-Basic#
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그
www.inflearn.com
페이징 API
JPA 는 페이징을 다음 두 API 로 추상화한다.
- setFirstResult(int startPosition) : 조회 시작위치(0 부터 시작)
- setMaxResults(int maxResult) : 조회할 데이터 수
- JpaMain.java
// 페이징 기능이 제대로 동작하는지 확인하기 위해 order by 를 통해 데이터들을 정렬해준다.
List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(1)
.setMaxResults(10)
.getResults();
System.out.println("result.s = " + result.size());
for(Member member1 : result){
System.out.println("member1 = " + member1);
}
- Hibernate SQL
Hibernate:
/* select
m
from
Member m
order by
m.age desc */ select
member0_.id as id1_0_,
member0_.age as age2_0_,
member0_.TEAM_ID as team_id4_0_,
member0_.username as username3_0_
from
Member member0_
order by
member0_.age desc limit ? offset ? // 페이징 기능 작동 확인
result.s = 0
/* 아무 데이터도 들어와 있지 않은 상태이기 때문에 size 의 값이 0 이 될 수 밖에 없고
Member 객체의 데이터 값 또한 정상적으로 출력되지 않는다.*/
이번엔 페이징 기능이 동작하는 것을 다시 한번 확인하기 위해 100 개의 Member 데이터를 insert 한 후 페이징 기능을 실행해보자.
- JpaMain.java
for (int i = 0; i < 100; i++){
Member member = new Member();
member.setUsername("member" + i);
member.setAge(i);
em.persist(member);
}
em.flush();
em.clear();
List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(1)
.setMaxResults(10)
.getResultList();
System.out.println("result.s = " + result.size());
for (Member member1 : result) {
System.out.println("member1 = " + member1);
}
- Hibernate SQL
Hibernate: /* 데이터가 내림차순 첫번째 부터 10번째 까지 잘 정렬되어 출력되는 것을 확인할 수 있다. */
/* select
m
from
Member m
order by
m.age desc */ select
member0_.id as id1_0_,
member0_.age as age2_0_,
member0_.TEAM_ID as team_id4_0_,
member0_.username as username3_0_
from
Member member0_
order by
member0_.age desc limit ? offset ?
result.s = 10
member1 = Member{id=99, username='member98', age=98}
member1 = Member{id=98, username='member97', age=97}
member1 = Member{id=97, username='member96', age=96}
member1 = Member{id=96, username='member95', age=95}
member1 = Member{id=95, username='member94', age=94}
member1 = Member{id=94, username='member93', age=93}
member1 = Member{id=93, username='member92', age=92}
member1 = Member{id=92, username='member91', age=91}
member1 = Member{id=91, username='member90', age=90}
member1 = Member{id=90, username='member89', age=89}
limit ? offset?
limit, offset 과 같은 키워드는 페이징 기능을 활용하는데 있어 h2 데이터베이스 방언에 맞게 나타난 것이다.
h2 데이터베이스의 페이징 표준은 limit, offset 이다.
여기서 만약 데이터베이스를 Oracle 로 바꾸면 키워드가 rownum 으로 나오게 된다.
- persistence.xml
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect"/>
- Hibernate SQL
Hibernate:
/* select
m
from
Member m
order by
m.age desc */ select
*
from
( select
row_.*,
rownum rownum_
from
( select
member0_.id as id1_0_,
member0_.age as age2_0_,
member0_.TEAM_ID as team_id4_0_,
member0_.username as username3_0_
from
Member member0_
order by
member0_.age desc ) row_
where
rownum <= ?
)
where
rownum_ > ?
result.s = 10
member1 = Member{id=99, username='member98', age=98}
member1 = Member{id=98, username='member97', age=97}
member1 = Member{id=97, username='member96', age=96}
member1 = Member{id=96, username='member95', age=95}
member1 = Member{id=95, username='member94', age=94}
member1 = Member{id=94, username='member93', age=93}
member1 = Member{id=93, username='member92', age=92}
member1 = Member{id=92, username='member91', age=91}
member1 = Member{id=91, username='member90', age=90}
member1 = Member{id=90, username='member89', age=89}
위의 Hibernate SQL 쿼리를 보면 select 문이 내부적으로 3번 중첩되며 실행되면서 마지막 중첩 select 문 안에 order by 가 실행되는데, Oracle 을 사용하면 작성하게 되는 일반적인 페이징 쿼리로 위와 같이 rownum 기법을 통한 페이징 기능을 select 문을 중첩하는 방식으로 수행하게 된다.
다음 글에서는 도메인 테이블 간 조인에 대해 알아보자.