Hibernate 3では、HQLで次のMySQLの制限と同等のことを行う方法はありますか?
select * from a_table order by a_table_column desc limit 0, 20;
できればsetMaxResultsを使いたくありません。これは古いバージョンのHibernate / HQLで確かに可能でしたが、消えてしまったようです。
Hibernate 3では、HQLで次のMySQLの制限と同等のことを行う方法はありますか?
select * from a_table order by a_table_column desc limit 0, 20;
できればsetMaxResultsを使いたくありません。これは古いバージョンのHibernate / HQLで確かに可能でしたが、消えてしまったようです。
回答:
これは、Hibernate 2では機能したがHibernate 3では機能しなかった理由について数年前にHibernateフォーラムに投稿されました。
Limitは、HQLでサポートされる句にはなりませんでした。setMaxResults()を使用するためのものです。
したがって、Hibernate 2で機能した場合は、仕様ではなく偶然によるものと思われます。私が考えるあなたには、いくつかのネイティブSQLでこっそりできるようにHibernate 2 HQLパーサーは、それはHQLとして認識することをクエリのビットを交換し、それがあったように残りの部分を残しているので、これはでした。ただし、Hibernate 3には適切なAST HQLパーサーがあり、許容度がかなり低くなっています。
私はQuery.setMaxResults()
本当にあなたの唯一の選択肢だと思います。
setMaxResults
から限られた数の結果行を取得してユーザーに表示します。 50レコードですが、それはしたくないのですが、クエリ自体は50レコードをクエリしたいのですが、それを行う方法はありますか?
setMaxResults
hibernateは、limit
パーツをクエリに追加します。すべての結果が得られるわけではありません。あなたは、有効にすることによって、それが生成するクエリを確認することができます<property name="show_sql">true</property>
// SQL: SELECT * FROM table LIMIT start, maxRows;
Query q = session.createQuery("FROM table");
q.setFirstResult(start);
q.setMaxResults(maxRows);
setFirstResult
、彼らはちょうど言うここで、他の場所のに対し、実際にこの回答に記載されているsetMaxResults
このおよびsetMaxResults
オフセットを設定する方法を言及することなく、そのに。
オブジェクトで使用setMaxResults()
したくないQuery
場合は、常に通常のSQLの使用に戻すことができます。
setMaxResultsを使用したくない場合は、listの代わりにQuery.scrollを使用して、必要な行をフェッチすることもできます。たとえば、ページングに役立ちます。
setMaxResults()
最初にメモリ内のすべてのレコードをロードしてから、サブリストを作成します。これにより、メモリが不足しているため、レコードが数十万以上ある場合にサーバーがクラッシュします。ただし、JPAタイプのクエリからHibernateクエリに進むことができQueryImpl hibernateQuery = query.unwrap(QueryImpl.class)
、その後、scroll()
提案された方法を使用できます。
これは非常に一般的な質問であるため、 この回答に基づいてこの記事を作成しました。
setFirstResult
setMaxResults
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
はデータベース固有のページネーションロジックを定義し、次の図に示すように、Hibernateは多くのデータベース固有のページネーションオプションをサポートしています。
これで、使用している基礎となるリレーショナルデータベースシステムに応じて、上記のJPQLクエリは適切なページネーション構文を使用します。
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 ?, ?
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 ?
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
は、Hibernateがサポートされているリレーショナルデータベースのデータベース固有のページネーション構文を生成できることです。
また、JPQLクエリのみに限定されません。ネイティブSQLクエリにはsetFirstResult
、setMaxResults
メソッド7を使用できます。
ネイティブ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 ?
かっこいいですよね?
フィルター処理と並べ替えの条件にインデックスを付けることができる場合、ページ分割は適切です。ページネーションの要件が動的フィルタリングを意味する場合、ElasticSearchなどの逆インデックスソリューションを使用する方がはるかに優れたアプローチです。
チェックアウトこの記事を詳細については。
String hql = "select userName from AccountInfo order by points desc 5";
これは使用せずに私のために働きました setmaxResults();
キーワードを使用せずに、最後の最大値(この場合は5)を指定するだけlimit
です。:P
このモードで制限を管理できる場合
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());
}
ネイティブクエリを作成する必要があります。これを参照してください。
@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);
@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);
Hibernate-5.0.12
ます。これはまだ利用できませんか?setMaxResults
@skaffmanの回答で@Rachelが気づいたように、100万件程度のレコードを取得してからフィルターを適用するのは非常に重いでしょう。