261

Hibernate 3では、HQLで次のMySQL制限と同等の方法がありますか?

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

可能であれば、setMaxResultsを使用したくありません。これは、Hibernate / HQLの古いバージョンでは間違いなく可能でしたが、消えたようです。

4

14 に答える 14

331

これは、Hibernate 2 では機能するのに Hibernate 3 では機能しない理由について尋ねられたときに、数年前に Hibernate フォーラムに投稿されました。

limitは HQL でサポートされる句ではありませんでした。setMaxResults() を使用することを意図しています。

したがって、Hibernate 2 で機能した場合は、設計ではなく偶然のようです。これは、Hibernate 2 HQL パーサーが HQL として認識したクエリのビットを置き換え、残りをそのままにして、ネイティブ SQL に忍び込むことができたためだと思います。ただし、Hibernate 3 には適切な AST HQL パーサーがあり、許容範囲がかなり狭くなっています。

私はQuery.setMaxResults()本当にあなたの唯一のオプションだと思います。

于 2009-08-06T15:37:53.363 に答える
153
 // SQL: SELECT * FROM table LIMIT start, maxRows;

Query q = session.createQuery("FROM table");
q.setFirstResult(start);
q.setMaxResults(maxRows);
于 2011-02-14T09:28:44.673 に答える
21

setMaxResults()オブジェクトで使用したくない場合は、Queryいつでも通常の SQL の使用に戻すことができます。

于 2009-08-06T15:36:54.597 に答える
6

setFirstResultメソッドとsetMaxResults Queryメソッド

JPA および HibernateQueryの場合、setFirstResultメソッドは と同等でOFFSETあり、setMaxResultsメソッドは LIMIT と同等です。

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

抽象LimitHandler

HibernateLimitHandlerはデータベース固有のページネーション ロジックを定義し、次の図に示すように、Hibernate は多くのデータベース固有のページネーション オプションをサポートします。

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サーバー

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

setFirstResultandを使用する利点setMaxResultsは、Hibernate がサポートされているリレーショナル データベースのデータベース固有のページネーション構文を生成できることです。

また、JPQL クエリだけに限定されません。setFirstResultおよびsetMaxResultsメソッド 7 をネイティブ SQL クエリに使用できます。

ネイティブ SQL クエリ

ネイティブ SQL クエリを使用する場合、データベース固有のページネーションをハードコーディングする必要はありません。Hibernate はそれをクエリに追加できます。

したがって、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();

Hibernate は次のように変換します。

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

かっこいいでしょ?

SQL ベースのページネーションを超えて

フィルタリングと並べ替えの条件にインデックスを付けることができる場合、ページネーションは適切です。ページネーションの要件が動的フィルタリングを意味する場合は、ElasticSearch などの逆インデックス ソリューションを使用する方がはるかに優れたアプローチです。

于 2020-02-25T07:35:54.747 に答える
5

setMaxResults を使用したくない場合は、list の代わりに Query.scroll を使用して、必要な行をフェッチすることもできます。たとえば、ページングに役立ちます。

于 2009-12-08T18:10:18.713 に答える
1

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

これは使用せずに私のために働いたsetmaxResults();

キーワードを使用せずに、最後に最大値 (この場合は 5) を指定するだけlimitです。:P

于 2011-01-12T06:46:30.443 に答える
0

このモードで制限を管理できる場合

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();
}

これは、制限またはリストを処理するための非常に単純なコードです。

于 2011-10-28T07:01:00.360 に答える
0

以下のクエリを使用できます

NativeQuery<Object[]> query = session.createNativeQuery(select * from employee limit ?)
query.setparameter(1,1);
于 2020-02-28T09:54:06.387 に答える
0

私の観察では、HQL (休止状態 3.x) に制限があっても、解析エラーが発生するか、無視されるだけです。(order by + desc/asc が limit の前にある場合は無視されます。limit の前に desc/asc がないと、解析エラーが発生します)

于 2010-07-27T06:11:34.747 に答える
-2
@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);
于 2019-03-15T07:10:48.683 に答える