9

JavaでHQLのビルダーを探しています。次のようなものを取り除きたい:

StringBuilder builder = new StringBuilder()
    .append("select stock from ")
    .append( Stock.class.getName() )
    .append( " as stock where stock.id = ")
    .append( id );

私はむしろ次のようなものが欲しいです:

HqlBuilder builder = new HqlBuilder()
    .select( "stock" )
    .from( Stock.class.getName() ).as( "stock" )
    .where( "stock.id" ).equals( id );

少しググったのですが、見つかりませんでした。

今のところ自分のニーズに合ったクイック&ダムを書きましたHqlBuilderが、私だけよりも多くのユーザーとテストがあるものを見つけたいと思っています。

注: Criteria API ではできなかった、次のようなことができるようになりたいと思います。

select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.someValue = bonus.id

すなわち。プロパティがボーナス テーブルから任意someValueのボーナスを指すすべての株式を選択します。

ありがとう!

4

11 に答える 11

9

問題に対するタイプセーフなアプローチについては、Querydslを検討してください。

クエリの例は次のようになります

HQLQuery query = new HibernateQuery(session);
List<Stock> s = query.from(stock, bonus)
  .where(stock.someValue.eq(bonus.id))
  .list(stock);

Querydslは、JPA2などのコード生成にAPTを使用し、JPA / Hibernate、JDO、SQL、およびJavaコレクションをサポートします。

私はQuerydslのメンテナーなので、この答えには偏りがあります。

于 2010-01-11T21:07:01.727 に答える
7

Criteria APIがそれをしてくれませんか? それはあなたが求めているものとほぼ同じように見えます。

于 2008-09-11T15:20:11.380 に答える
5

別のタイプ セーフなクエリ DSL については、http://www.torpedoquery.orgをお勧めします。ライブラリはまだ新しいですが、エンティティのクラスを直接使用することでタイプ セーフを提供します。これは、リファクタリングまたは再設計の前にクエリが適用されなくなった場合の初期のコンパイラ エラーを意味します。

例もご紹介しました。あなたの投稿から、サブクエリの制限を行おうとしていると思うので、それに基づいて例を作成しました。

import static org.torpedoquery.jpa.Torpedo.*;

Bonus bonus = from(Bonus.class);
Query subQuery = select(bonus.getId());

Stock stock = from(Stock.class);
where(stock.getSomeValue()).in(subQuery);

List<Stock> stocks = select(stock).list(entityManager);
于 2011-12-04T02:21:35.400 に答える
5

@ Sébastien Rocca-Serra
今、私たちはどこか具体的なところに来ています。実行しようとしている結合の種類は、Criteria API では実際には不可能ですが、サブクエリは同じことを達成する必要があります。最初DetachedCriteriaにボーナス テーブルの を作成し、次にIN演算子 for を使用しsomeValueます。

DetachedCriteria bonuses = DetachedCriteria.forClass(Bonus.class);
List stocks = session.createCriteria(Stock.class)
    .add(Property.forName("someValue").in(bonuses)).list();

これは、

select stock
from com.something.Stock as stock
where stock.someValue in (select bonus.id from com.something.Bonus as bonus)

唯一の欠点は、異なるテーブルへの参照がsomeValueあり、ID がすべてのテーブルで一意でない場合です。しかし、クエリには同じ欠陥があります。

于 2008-09-11T17:02:48.123 に答える
4

Hibernate に組み込まれている Criteria クエリ API を使用したいようです。上記のクエリを実行すると、次のようになります。

List<Stock> stocks = session.createCriteria(Stock.class)
    .add(Property.forName("id").eq(id))
    .list();

まだ Hibernate セッションにアクセスできない場合は、次のように「DetachedCriteria」を使用できます。

DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class) 
    .add(Property.forName("id").eq(id));

特定の ID を持つボーナスを持つすべての株式を取得したい場合は、次のようにします。

DetachedCriteria criteria = DetachedCriteria.forClass(Stock.class)
     .createCriteria("Stock")
          .add(Property.forName("id").eq(id)));

詳細については、Hibernate ドキュメントのCriteria Queriesを確認してください。

于 2008-09-11T15:27:56.527 に答える
2

hibernate-generic-daoプロジェクトから入手できる検索パッケージを見てください。これはかなりまともな HQL Builder の実装です。

于 2009-12-02T20:10:15.523 に答える
2

私は、あなたの状況に合わせて簡単に構築できる OMERO 用の GPL ソリューションを作成しました。

使用法:

QueryBuilder qb = new QueryBuilder();
qb.select("img");
qb.from("Image", "img");
qb.join("img.pixels", "pix", true, false);

// Can't join anymore after this
qb.where(); // First
qb.append("(");
qb.and("pt.details.creationTime > :time");
qb.param("time", new Date());
qb.append(")");
qb.and("img.id in (:ids)");
qb.paramList("ids", new HashSet());
qb.order("img.id", true);
qb.order("this.details.creationEvent.time", false);

これは、「select->from->join->where->order」などのステート マシンとして機能し、オプションのパラメーターに対応します。Criteria API が実行できないクエリがいくつかあったため ( HHH-879を参照)、最終的には、この小さなクラスを記述して StringBuilder をラップする方が簡単でした。(注: 2 つを統合する必要がある Hibernate ブランチを説明するチケットHHH-2407があります。その後、Criteria API に再度アクセスすることはおそらく理にかなっています)

于 2009-02-25T15:15:04.230 に答える
2

@セバスチャン・ロッカ・セラ

select stock
from com.something.Stock as stock, com.something.Bonus as bonus
where stock.bonus.id = bonus.id

それは単なる結合です。StockHibernate は、とBonussetupの間のマッピングがあり、bonusが のプロパティである場合にのみ、自動的にそれを行いますStock。はオブジェクトCriteria.list()を返すので、 を呼び出すだけです。Stockstock.getBonus()

次のようなことをしたい場合は、注意してください

select stock
from com.something.Stock as stock
where stock.bonus.value > 1000000

を使用する必要がありますCriteria.createAlias()。それは次のようなものでしょう

session.createCriteria(Stock.class).createAlias("bonus", "b")
   .add(Restrictions.gt("b.value", 1000000)).list()
于 2008-09-11T15:42:11.360 に答える
2

Criteria API は、HQL で利用可能なすべての機能を提供するわけではありません。たとえば、同じ列に対して複数の結合を行うことはできません。

NAMED QUERIESを使用しないのはなぜですか? よりクリーンな外観:

Person person = session.getNamedQuery("Person.findByName")
                             .setString(0, "Marcio")
                             .list();
于 2008-09-11T17:32:59.253 に答える
2

このスレッドがかなり古いことは知っていますが、HqlBuilder も探していました。この「スクリーンセーバー」プロジェクト
を見つけました。これ は Windows のスクリーンセーバーではなく、ハイスループット スクリーニング (HTS) 施設用の「ラボ情報管理システム (LIMS) 」です。小分子および RNAi スクリーニングを実行します。

非常に見栄えの良い HQLBuilder が含まれています。
使用可能なメソッドのサンプル リストを次に示します。

...
HqlBuilder select(String alias);
HqlBuilder select(String alias, String property);
HqlBuilder from(Class<?> entityClass, String alias);
HqlBuilder fromFetch(String joinAlias, String joinRelationship, String alias);
HqlBuilder where(String alias, String property, Operator operator, Object value);
HqlBuilder where(String alias, Operator operator, Object value);
HqlBuilder where(String alias1, Operator operator, String alias2);
HqlBuilder whereIn(String alias, String property, Set<?> values);
HqlBuilder whereIn(String alias, Set<?> values);
HqlBuilder where(Clause clause);
HqlBuilder orderBy(String alias, String property);
HqlBuilder orderBy(String alias, SortDirection sortDirection);
HqlBuilder orderBy(String alias, String property, SortDirection sortDirection);
String toHql();
...
于 2009-12-10T10:38:12.620 に答える