我遇到(键,值)实体搜索问题。
我不知道如何编写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)的文档
客户端可能提供两个以上的参数。
先谢谢
答案 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();