1

次の状況を想定してみましょう: Person と Comment の 2 つのエンティティ クラスがあります。

//Person class
@Entity
public class Person extends AbstractBusinesObject{

@OneToMany(mappedby ="owner")
private List<Comment> comments;

//Comment class
@Entity
public class Comment extends AbstractBusinesObject{

@ManyToOne
private Person owner;

特定のコメントが特定の人物のものかどうかを判断するために、次の 2 つの選択肢からどちらのアプローチが優れているか (パフォーマンス、メモリ効率) を知りたいです。

public boolean isUsersComment(Person p, Comment c){
    return p.getComments().contains(c);
}

また

public boolean isUsersComment(Person p, Comment c){
    CriteriaBuilder cb = getEntitymanager().getCriteriaBuilder();
    CriteriaQuery<Comment> cq = cb.createQuery(Comment.class);
    Root<Comment> root = cq.from(Comment.class);
    cq.select(root).where(cb.and(cb.equal(root, c), cb.isTrue(root.in(p.getComments())));
    try{
        getEntityManager().createQuery(cq).getSingleResult();
        return true;
    } catch (NoResultException ex){
        return false;
    } catch (NoUniqueResultException ex){
        throw new IllegalStateException(message);
    }
}

私の知る限り、クライテリア API はデータベース クエリを生成しますが、最初のソリューションはコレクションを検索します。

ご回答ありがとうございます。

ps: Criteria API は初めてなので、修正や提案も受け付けます。

編集

わかりました、それはばかげた質問であることがわかりました。双方向の関係を宣言したので、解決策は非常に簡単です。

return c.getOwner.equals(p);

とにかく、一方向の関係の場合のアプローチは何ですか?

4

1 に答える 1

0

元のコレクションが既にロードされているかどうかによって異なりますか? Collection がロードされている場合は、contains() 呼び出しが直接行われます。それ以外の場合は、クエリ (Criteria または JPQL) が行うことと同等になる可能性があります。

コレクションが大きい場合は、常にクエリを実行します (コレクション全体をロードしたくないため)。それ以外の場合は Collection.contains を使用します

于 2013-04-10T09:18:02.120 に答える