HQLでDistinctクエリを作成する方法
質問
HQLでDistinctクエリを作成する方法はありますか。 「個別」を使用するか、キーワードまたはその他の方法。 distinctがHQLの有効なキーワークであるかどうかはわかりませんが、HQLに相当するSQLキーワードの「distinct」を探しています。
解決
これは、使用するhqlのスニペットです。 (IDを保護するために名前が変更されました)
String queryString = "select distinct f from Foo f inner join foo.bars as b" +
" where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
他のヒント
HQLの distinct
キーワードは、SQLの distinct
キーワードに直接マップしないことに注意してください。
HQLで distinct
キーワードを使用すると、Hibernateは distinct
SQLキーワードを使用する場合がありますが、場合によっては結果トランスフォーマーを使用して異なる結果を生成します。たとえば、次のような外部結合を使用している場合:
select distinct o from Order o left join fetch o.lineItems
この場合、SQLレベルで重複を除外することはできないため、Hibernateは ResultTransformer
を使用して、SQLクエリが実行された後、 重複を除外します。
次回このようなことをする
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
Hibernate HQLクエリで Criteria.DISTINCT_ROOT_ENTITY
を使用することもできます。
例:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
HQLクエリと組み合わせた結果トランスフォーマーに問題がありました。試したとき
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
動作しませんでした。このように手動で変換する必要がありました:
final List found = trans.transformList(qry.list());
Criteria APIトランスフォーマーで問題なく動作しました。
モデルでは、メインクエリは次のようになりました。
@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd",
query = "select distinct i from CentralFinancialAgencyAccountCd i")
そして、私はまだ「明確な」と考えていたものを得ていませんでした。結果。これらは、テーブル上の主キーの組み合わせに基づいて区別されました。
だから、 DaoImpl
に1行の変更を追加し、最終的に&quot; distinct&quot;を取得しました。私が欲しかった戻ります。たとえば、00を4回表示する代わりに、1回だけ表示します。 DaoImpl
に追加したコードは次のとおりです。
@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {
Session session = (Session) entityManager.getDelegate();
org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
List<CacheModelBase> codes;
codes = q.list();
return codes;
}
これがお役に立てば幸いです!繰り返しますが、これは、サービス、dao、およびモデルタイプのプロジェクトを実装するコーディングプラクティスに従う場合にのみ機能する可能性があります。
CUSTOMER_INFORMATIONテーブルにマッピングされた顧客エンティティがあり、顧客の個別のfirstNameのリストを取得するとします。以下のスニペットを使用して同じものを取得できます。
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
お役に立てば幸いです。そのため、ここでは個別のキーワードを使用する代わりにgroup byを使用しています。
また、以前は、複数の列に適用する際に個別のキーワードを使用することは困難でした。たとえば、個別のfirstName、lastName、group byのリストを取得したい場合は、単に機能します。この場合、distinctを使用するのは困難でした。
このような条件ビルダーで、独自のキーワードを使用できます。
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));
モデルクラスでフィールドコンストラクターを作成します。
異なるフィールドを使用するためのHibernate Query Languageの回答があります。 * SELECT DISTINCT(TO_CITY)FROM FLIGHT_ROUTE *を使用できます。 SQL クエリを使用すると、文字列リストが返されます。 Entity Classごとに戻り値を使用することはできません。 したがって、このタイプの問題を解決するための答えは、 SQL で HQL を使用することです。
FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);
SQL クエリステートメントからDISTINCT ROUTE_IDを取得し、リストとして入力しました。 INクエリは、IN(リスト)とは異なるTO_CITYをフィルターします。
戻り値の型はエンティティBean型です。 そのため、 AutoComplement などのAJAXで実行できます。
大丈夫かもしれません