[java] JPQL 또는 HQL에서 제한 쿼리를 어떻게 수행합니까?

최대 절전 모드 3에서는 HQL에서 다음과 같은 MySQL 제한을 수행하는 방법이 있습니까?

select * from a_table order by a_table_column desc limit 0, 20;

가능한 경우 setMaxResults를 사용하고 싶지 않습니다. 이것은 이전 버전의 Hibernate / HQL에서 가능했지만 사라진 것 같습니다.



답변

이것은 왜 Hibernate 2에서는 작동했지만 Hibernate 3에서는 작동하지 않는지에 대해 물었을 때 Hibernate 포럼 에 게시 되었습니다.

HQL에서는 제한이 지원되는 조항 이 아닙니다 . setMaxResults ()를 사용해야합니다.

따라서 최대 절전 모드 2에서 작동하면 디자인이 아니라 우연의 일치 인 것 같습니다. 내가 생각하는 일부 네이티브 SQL에 몰래 수 있도록 최대 절전 모드 2 HQL 파서, 그것은 HQL로 인식하는 쿼리의 비트를 교체하고 그것이로 나머지를 떠날 것 때문이었다. 그러나 최대 절전 모드 3에는 적절한 AST HQL 파서가 있으며 훨씬 덜 용서합니다.

Query.setMaxResults()정말 유일한 옵션 이라고 생각 합니다.


답변

 // SQL: SELECT * FROM table LIMIT start, maxRows;

Query q = session.createQuery("FROM table");
q.setFirstResult(start);
q.setMaxResults(maxRows);


답변

사용하지 않으려면 setMaxResults()상의 Query객체 다음 수 정상적인 SQL을 사용하여 항상 되돌리기 다시.


답변

setMaxResults를 사용하지 않으려면 list 대신 Query.scroll을 사용하여 원하는 행을 가져올 수 있습니다. 예를 들어 페이징에 유용합니다.


답변

이를 위해 페이지 매김을 쉽게 사용할 수 있습니다.

    @QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value = "true") })
    @Query("select * from a_table order by a_table_column desc")
    List<String> getStringValue(Pageable pageable);

new PageRequest(0, 1)레코드를 가져오고 목록에서 첫 번째 레코드 를 가져 오려면 전달해야 합니다 .


답변

이것은 매우 일반적인 질문 이므로이 답변을 기반으로하는이 기사를 작성
했습니다.

setFirstResultsetMaxResults Query방법

JPA 및 Hibernate의 Query경우, setFirstResult메소드 는와 동일 OFFSET하며 setMaxResults메소드는 LIMIT와 같습니다.

List<Post> posts = entityManager
.createQuery(
    "select p " +
    "from Post p " +
    "order by p.createdOn ")
.setFirstResult(10)
.setMaxResults(10)
.getResultList();

LimitHandler추상화

Hibernate LimitHandler는 데이터베이스 특정 페이지 매김 로직을 정의하고, 다음 다이어그램에서 보여 지듯이, 많은 데이터베이스 특정 페이지 매김 옵션을 지원합니다.

<code> LimitHandler </ code> 구현

이제 사용중인 기본 관계형 데이터베이스 시스템에 따라 위의 JPQL 쿼리는 적절한 페이지 매김 구문을 사용합니다.

MySQL

SELECT p.id AS id1_0_,
       p.created_on AS created_2_0_,
       p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?, ?

PostgreSQL

SELECT p.id AS id1_0_,
       p.created_on AS created_2_0_,
       p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?

SQL 서버

SELECT p.id AS id1_0_,
       p.created_on AS created_on2_0_,
       p.title AS title3_0_
FROM post p
ORDER BY p.created_on
OFFSET ? ROWS
FETCH NEXT ? ROWS ONLY

신탁

SELECT *
FROM (
    SELECT
        row_.*, rownum rownum_
    FROM (
        SELECT
            p.id AS id1_0_,
            p.created_on AS created_on2_0_,
            p.title AS title3_0_
        FROM post p
        ORDER BY p.created_on
    ) row_
    WHERE rownum <= ?
)
WHERE rownum_ > ?

사용의 장점 setFirstResultsetMaxResults최대 절전 모드가 지원되는 관계형 데이터베이스에 대한 데이터베이스 특정 페이지 매김 구문을 생성 할 수 있다는 것입니다.

또한 JPQL 쿼리에만 국한되지 않습니다. 네이티브 SQL 쿼리에 setFirstResultand 및 setMaxResultsmethod 7을 사용할 수 있습니다 .

기본 SQL 쿼리

기본 SQL 쿼리를 사용할 때 데이터베이스 별 페이지 매김을 하드 코딩 할 필요가 없습니다. 최대 절전 모드로 쿼리에 추가 할 수 있습니다.

따라서 PostgreSQL에서이 SQL 쿼리를 실행하는 경우 :

List<Tuple> posts = entityManager
.createNativeQuery(
    "SELECT " +
    "   p.id AS id, " +
    "   p.title AS title " +
    "from post p " +
    "ORDER BY p.created_on", Tuple.class)
.setFirstResult(10)
.setMaxResults(10)
.getResultList();

최대 절전 모드는 다음과 같이 변환합니다.

SELECT p.id AS id,
       p.title AS title
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?

멋지죠?

SQL 기반 페이지 매김을 넘어

페이지 매김은 필터링 및 정렬 기준을 색인 할 수있을 때 좋습니다. 페이지 매김 요구 사항이 동적 필터링을 의미하는 경우 ElasticSearch와 같은 역 인덱스 솔루션을 사용하는 것이 훨씬 좋습니다.

확인 이 문서 자세한 내용을.


답변

String hql = "select userName from AccountInfo order by points desc 5";

이것은 사용하지 않고 나를 위해 일했습니다. setmaxResults();

keyword를 사용하지 않고 마지막 값 (이 경우 5)에 최대 값을 제공하십시오 limit. :피