我有一个实体:
@Entity
class A {
@Id
@Column
private Long id;
@ElementCollection
@MapKeyColumn(name="key")
@Column(name="value")
@CollectionTable(name="key_value_pairs", joinColumns=@JoinColumn(name="a_id"))
private Map<String, String> metadata;
}
...我有一个JPARepository:
public interface ARepository extends JpaRepository<A, Long> {
@Query("...")
Page<A> getAllAsThatHaveAtleastOneEntrysetPairOfGivenMapInMetadataMap(Map<String, String> mapToCompareAgainst, Pageable pageable);
}
问题是我不知道如何制定该查询,或者甚至可以在JPQL中使用? 所以基本上我想要查询要做的是,获取mapToCompareAgainst的所有键值对,并将它们逐个地与每个元素A的元数据进行比较所有键值对并选择至少找到一个完整匹配的元素(例如键和该值在持久化元素和给定的映射条目中都是相同的。
(代码示例是松散类型的,可能会有一些小缺陷,在这种情况下我很抱歉。它们只是为了说明手头的问题。现实生活实体有点复杂。)
修改
我找到了一种方法来检查一对(而不是地图中的所有对)来自https://stackoverflow.com/a/23961780/3020903:
@Query("select a from A a where (KEY(a.metadata) = :key and :value in (VALUE(a.metadata)))")
Page<A> getAllAsThatHaveAtleastOneGivenPairInMetadataMap(@Param("key") String key, @Param("value") String value, Pageable pageable);
所以我可以在map entryset的循环中完成这些查询并连接结果,但是后来我无法控制分页和重复,所以我仍然在第一个。
修改2
实际上即使这种“检查一对”查询也不起作用。它实际上做的是返回具有指定键的所有元素,但仅当映射中存在指定的值时(但它不一定必须是指定键的对)。所以还是在第一个方面。
编辑3
我得到了一个键值对匹配查询,并且随着需求的变化,现在已经足够了。仍然很高兴知道如何解决最初的问题。一个键值对解决方案:
@Query("select a from A a JOIN a.metadata md where KEY(md) = :key and :value = md")
Page<A> getAllAsThatHaveAtleastOneGivenPairInMetadataMap(@Param("key") String key, @Param("value") String value, Pageable pageable);