web-dev-qa-db-ja.com

INとMEMBER OF JPQL演算子の違いは何ですか?

INとMEMBER OF JPQL演算子の違いは何ですか?

40
faermanj

INテストは、クエリに指定した(またはサブクエリ経由で取得した)値の単一値パス式(エンティティの永続属性)の値です。

MEMBER OFテストは、エンティティのコレクションの値のメンバーをクエリするために提供した値(または式で定義した値)です。

次のサンプルエンティティを使用してみましょう。

@Entity
public class EntityA {
    private @Id Integer id;
    private Integer someValue;
    @ElementCollection
    List<Integer> listOfValues;

    public EntityA() { }

    public EntityA(Integer id, Integer someValue, List<Integer> listOfValues) {
        this.id = id;
        this.someValue = someValue;
        this.listOfValues = listOfValues;
    }
}

そして、次のテストデータ:

EntityA a1 = new EntityA(1, 1, Arrays.asList(4, 5, 6));
EntityA a2 = new EntityA(2, 2, Arrays.asList(7, 8, 9));

次のクエリでは、someValueが(0,1,3)の1つであるため、結果としてa1を取得します。クエリでリテラルを使用すると(SELECT a FROM EntityA a WHERE a.someValue IN(0、1、3))同じ結果が生成されます。

TypedQuery<EntityA> queryIn = em.createQuery(
    "SELECT a FROM EntityA a WHERE a.someValue IN :values", EntityA.class);
queryIn.setParameter("values", Arrays.asList(0, 1, 3));
List<EntityA> resultIn = queryIn.getResultList();

次のクエリでは、7がlistOfValuesの値の1つであるため、結果としてa2を取得します。

TypedQuery<EntityA> queryMemberOf = em.createQuery(
    "SELECT a FROM EntityA a WHERE :value MEMBER OF a.listOfValues", EntityA.class);
queryMemberOf.setParameter("value", 7);
List<EntityA> resultMemberOf = queryMemberOf.getResultList();

この機能(パラメーターとしてのコレクションを含む)は、JPA 2.0仕様で定義されており、Hibernateに固有ではありません(上記のコードは、たとえばEclipseLinkで機能します)。

50
Mikko Maunu

INは、値がリテラルまたはクエリパラメーターの明示的な固定リストの1つであるかどうかをテストします。

MEMBER OFは、値がJPAコレクション、つまり実際にオブジェクトモデルの一部であるコレクションに存在するかどうかをテストします。

10