在键值实体中搜索

时间:2017-02-12 12:19:44

标签: jpa jpql

萨拉姆,

我遇到(键,值)实体搜索问题。

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

我有文件实体,映射到oneToMany" MetaData"实体

@Entity
public class Document implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="id_document")
    private Integer idDocument;

    @Column(name="date_enregistrement")
    private Timestamp dateEnregistrement;

    // other columns

    //bi-directional many-to-one association to MetaData
    @OneToMany(mappedBy="document")
    private List<MetaData> metaData;

    /*
     getters and setters
    */
}

和MetaData实体

@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
    */

}

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

示例:

查找sender(key = sender)为Youssef(value = Youssef)且receiver(key)为Hamza(value)的文档

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

先谢谢

1 个答案:

答案 0 :(得分:1)

由于键值对的数量可能不同,我建议使用CriteraQuery以获得更多灵活性:

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();