Jpa 在键值实体中搜索

Jpa 在键值实体中搜索,jpa,jpql,Jpa,Jpql,萨拉姆 我对(键、值)实体搜索有问题 我不知道如何编写jpql查询来搜索。。这是我的问题 我有文档实体,映射到oneToMany“元数据”实体 我想做的是通过提供一些元数据作为参数来搜索文档 示例: 查找发送方(key=sender)为Youssef(value=Youssef),接收方(key)为Hamza(value)的文档 客户端可能提供两个以上的参数 感谢advace,因为键值对的数量可能会有所不同,我建议使用CriterQuery以获得更大的灵活性: CriteriaBuilder c

萨拉姆

我对(键、值)实体搜索有问题

我不知道如何编写jpql查询来搜索。。这是我的问题

我有文档实体,映射到oneToMany“元数据”实体

我想做的是通过提供一些元数据作为参数来搜索文档

示例:

查找发送方(key=sender)为Youssef(value=Youssef),接收方(key)为Hamza(value)的文档

客户端可能提供两个以上的参数


感谢advace

,因为键值对的数量可能会有所不同,我建议使用CriterQuery以获得更大的灵活性:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Document> query = criteriaBuilder.createQuery(Document.class);
Root<Document> root = query.from(Document.class);
Join<Document, MetaData> metadataJoin = root.join("metaData", JoinType.INNER);
List<Predicate> predicateList = new LinkedList<Predicate>();
//If a map contains all your key value pairs
for(Map.Entry<String, String> entry : keyValueMap.entrySet()){
  predicateList.add(
    criteriaBuilder.and(
      criteriaBuilder.equal(metadataJoin.get("key"), entry.getKey()), 
      criteriaBuilder.equal(metadataJoin.get("value"), entry.getValue())
    )
  );
}
query.where(criteriaBuilder.or(
  predicateList.toArray(new Predicate[predicateList.size()]))
)
query.groupBy(root.get("idDocument"));
query.having(criteriaBuilder.equal(criteriaBuilder.count(root.get("idDocument")), predicateList.size()));
List<Document> documentList = entityManager.createQuery(query).getResultList();
CriteriaBuilder-CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery=criteriaBuilder.createQuery(Document.class);
Root=query.from(Document.class);
Join metadataJoin=root.Join(“元数据”,JoinType.INNER);
List predicateList=新建LinkedList();
//如果映射包含所有键值对
对于(Map.Entry:keyValueMap.entrySet()){
谓词列表添加(
标准构建器(
criteriaBuilder.equal(metadataJoin.get(“key”),entry.getKey()),
criteriaBuilder.equal(metadataJoin.get(“value”),entry.getValue()
)
);
}
query.where(criteriaBuilder.or)(
predicateList.toArray(新谓词[predicateList.size()]))
)
groupBy(root.get(“idDocument”);
having(criteriaBuilder.equal(criteriaBuilder.count(root.get(“idDocument”)),predicateList.size());
List documentList=entityManager.createQuery(query.getResultList();

那么,查找包含元数据且具有特定键/值对(且所有给定对都必须存在)的文档是正确的吗?是的:(@Maciej Kowalski什么是
:metadataList
应该包含?JPA将在
中的
语句中执行身份比较,而问题说明只有
键/值对可以作为输入使用。我从来没有使用过CriteriaQuery,明天我将在我的电脑旁边尝试,thx;)
@Entity
@Table(name="meta_data")
public class MetaData implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="id_meta_data")
    private Integer idMetaData;

    @Column(name="key")
    private String key;

    @Column(name="value")
    private String value;

    //bi-directional many-to-one association to Document
    @ManyToOne
    @JoinColumn(name="id_document")
    private Document document;

    /*
     getters and setters
    */

}
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Document> query = criteriaBuilder.createQuery(Document.class);
Root<Document> root = query.from(Document.class);
Join<Document, MetaData> metadataJoin = root.join("metaData", JoinType.INNER);
List<Predicate> predicateList = new LinkedList<Predicate>();
//If a map contains all your key value pairs
for(Map.Entry<String, String> entry : keyValueMap.entrySet()){
  predicateList.add(
    criteriaBuilder.and(
      criteriaBuilder.equal(metadataJoin.get("key"), entry.getKey()), 
      criteriaBuilder.equal(metadataJoin.get("value"), entry.getValue())
    )
  );
}
query.where(criteriaBuilder.or(
  predicateList.toArray(new Predicate[predicateList.size()]))
)
query.groupBy(root.get("idDocument"));
query.having(criteriaBuilder.equal(criteriaBuilder.count(root.get("idDocument")), predicateList.size()));
List<Document> documentList = entityManager.createQuery(query).getResultList();