IT이야기

JPQL 또는 HQL에서 제한 조회를 어떻게 하는가?

cyworld 2022. 5. 25. 22:19
반응형

JPQL 또는 HQL에서 제한 조회를 어떻게 하는가?

최대 절전 모드 3에서 HQL에 다음 MySQL 제한과 동등한 방법을 사용할 수 있는가?

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

가능하면 setMaxResults를 사용하고 싶지 않다.이것은 확실히 이전 버전의 겨울잠/HQL에서는 가능했지만, 사라진 것 같다.

는 몇 년 전 '동면 모드 2'에서는 작동하지만 '동면 모드 3'에서는 작동하지 않는 이유에 대한 질문으로 '동면 모드 3' 포럼에 게시되었다.

HQL에서 Limit는 결코 지원되는 조항이 아니었다.setMaxResults()를 사용하도록 되어 있다.

그래서 만약 그것이 겨울잠 2에서 효과가 있었다면, 그것은 계획적인 것이 아니라 우연에 의한 것으로 보인다.생각에 이것은 겨울잠 2 HQL 파서가 HQL로 인식한 쿼리의 비트를 대체하고 나머지는 그대로 두기 때문에 당신은 몇몇 네이티브 SQL을 몰래 들여올 수 있을 것이다.하지만 겨울잠 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을 사용하여 되돌릴 수 있다.

setFirstResult그리고setMaxResults Query방법들

JPA 및 최대 절전 모드용QuerysetFirstResult방법은 에 해당된다.OFFSET, 그리고setMaxResults메소드는 LIMIT에 해당한다.

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

LimitHandler추상화

겨울잠LimitHandler데이터베이스별 페이지 지정 논리를 정의하고, 다음 다이어그램에서 표시한 대로, 최대 절전 모드에서는 많은 데이터베이스 특정 페이지 지정 옵션을 지원한다.

LimitHandler 구현

이제 사용 중인 기본 관계형 데이터베이스 시스템에 따라 위의 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 Server

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_ > ?

사용의 이점setFirstResult그리고setMaxResults최대 절전 모드에서는 지원되는 모든 관계형 데이터베이스에 대해 데이터베이스별 페이지 지정 구문을 생성할 수 있다.

그리고, 당신은 JPQL 질의에만 국한되지 않는다.당신은 그것을 사용할 수 있다.setFirstResult그리고setMaxResults기본 SQL 쿼리에 대한 방법 7.

기본 SQL 쿼리

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

Postgre에서 이 SQL 쿼리를 실행하는 경우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와 같은 역색인 솔루션을 사용하는 것이 훨씬 더 좋은 방법이다.

setMaxResults를 사용하지 않으려면 목록 대신 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)레코드를 가져오거나 목록에서 첫 번째 레코드를 가져오십시오.

네이티브 쿼리를 작성해야 해, 이걸 참고해.

@Query(value =
    "SELECT * FROM user_metric UM WHERE UM.user_id = :userId AND UM.metric_id = :metricId LIMIT :limit", nativeQuery = true)
List<UserMetricValue> findTopNByUserIdAndMetricId(
    @Param("userId") String userId, @Param("metricId") Long metricId,
    @Param("limit") int limit);

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

이것은 사용하지 않고 나에게 효과가 있었다.setmaxResults();

키워드를 사용하지 않고 마지막(이 경우 5)의 최대값만 제공limit. :P. :P

내가 관찰한 바로는 HQL(하이버나이트 3.x)에 한계가 있다 하더라도 구문 분석 오류를 일으키거나 그냥 무시될 것이다.(한계 전 + desc/desc에 의한 오더가 있으면 무시되고, 제한 전 desc/desc가 없으면 구문 분석 오류가 발생한다)

이 모드에서 제한을 관리할 수 있는 경우

public List<ExampleModel> listExampleModel() {
    return listExampleModel(null, null);
}

public List<ExampleModel> listExampleModel(Integer first, Integer count) {
    Query tmp = getSession().createQuery("from ExampleModel");

    if (first != null)
        tmp.setFirstResult(first);
    if (count != null)
        tmp.setMaxResults(count);

    return (List<ExampleModel>)tmp.list();
}

이것은 제한이나 목록을 처리하기 위한 정말 간단한 코드다.

Criteria criteria=curdSession.createCriteria(DTOCLASS.class).addOrder(Order.desc("feild_name"));
                criteria.setMaxResults(3);
                List<DTOCLASS> users = (List<DTOCLASS>) criteria.list();
for (DTOCLASS user : users) {
                System.out.println(user.getStart());
            }

아래 쿼리를 사용할 수 있음

NativeQuery<Object[]> query = session.createNativeQuery(select * from employee limit ?)
query.setparameter(1,1);

아래 코드 조각은 HQL을 사용하여 한계 조회를 수행하는 데 사용된다.

Query query = session.createQuery("....");
query.setFirstResult(startPosition);
query.setMaxResults(maxRows);

링크에서 데모 어플리케이션을 받을 수 있다.

@Query(nativeQuery = true,
       value = "select from otp u where u.email =:email order by u.dateTime desc limit 1")
public List<otp> findOtp(@Param("email") String email);

참조URL: https://stackoverflow.com/questions/1239723/how-do-you-do-a-limit-query-in-jpql-or-hql

반응형