27

Cat クラスと Owner クラスがあります。猫の飼い主は 1 人ですが、飼い主は複数の猫を飼うことができます。私がクエリしたいのは、青い目の猫を飼っているすべての所有者を取得することです。

class Cat {
    Owner owner; //referenced from Owner.id
    String eyeColor;
}

class Owner {
    List<Cat> catList;
}

いくつかのコードを試しましたが、何をすべきか本当にわかりません。

Criteria criteria = getCurrentSession().createCriteria(cat.getClass(), "cat");
criteria.createAlias("cat.owner", "owner");    
criteria.add(Restrictions.eq("cat.eyeColor", "blue");
4

2 に答える 2

48

基準は、プロジェクションまたはルート エンティティのみを選択できます。結合されたエンティティではありません。そのため、一部のクエリは Criteria で表現することができません (これは、読みやすさと簡潔さに加えて、HQL を使用するもう 1 つの正当な理由です)。

ただし、関連付けは双方向であるため、ここですべてが失われるわけではありません。したがって、HQL クエリに相当するものだけが必要です。

select distinct owner from Owner owner 
join owner.cats cat 
where cat.eyeColor = 'blue'

どれが

Criteria c = session.createCriteria(Owner.class, "owner");
c.createAlias("owner.cats", "cat");
c.add(Restrictions.eq("cat.eyeColor", "blue");
c.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
于 2013-07-17T14:03:13.917 に答える
4

これを試して:

DetachedCriteria dc = DetachedCriteria.forClass(Cat.class, "inner")
    .add(Restrictions.eq("eyeColor", "blue"))
    .add(Restrictions.eqProperty("inner.owner", "outer.id"));

session.createCriteria(Owner.class, "outer")
    .add(Subqueries.exists(dc))
    .list();

distinctこれはデータベースでインデックスを使用でき、@JB Nizet のバージョンのようにメモリ内操作を実行しません(そこにある私のコメントを参照してください)。インデックスは次のようになります。

CREATE INDEX idx_cat_owner_eyecolor ON Cat(fkOwner, eyeColor)

distinct操作 (SQL またはメモリ内のいずれか) をコードの匂いと考えてください。めったに使用されず、多くの初心者プログラマーが「なぜこの行が2回あるのか」という問題を解決するために使用します。この場合のように、ほとんどの場合、書き換えることができます。必要な場合のユースケースはほとんどありません。

于 2015-03-12T07:10:03.003 に答える