gpt4 book ai didi

java - jpa条件查询,匹配作为参数传递的任何列表

转载 作者:行者123 更新时间:2023-12-02 01:46:15 24 4
gpt4 key购买 nike

我正在尝试编写一个 DAO 方法,在其中选择任意数量的具有匹配标签的小部件。所以在像这样的实体中:

@Entity
public class Widget {
@Id
private id;

@OneToMany (cascade = CascadeType.ALL)
private List<Tag> tagList;
}


@Entity
public class Tag {
@Id
private int id;

String tagValue;
}

在我的 DAO 中,我正在尝试编写一个接受字符串列表的方法

List<String> myList = new ArrayList<String>();
myList.add("tom");
myList.add("dick");
myList.add("harry");

到 DAO

public List<Widget> getWidgetsMatchingTags(EntityManager entityManager, List<String> tagValues) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Widget> query = cb.createQuery(Widget.class);
Root<Widget> widgetRoot = query.from(Widget.class);
Join<Widget, Tag> tagJoin = widgetRoot.join(Widget_.tagList);

// this works
query.select(widgetRoot).where(cb.and(
cb.equal(tagJoin.get(Tag_.value), "tom")));

// but if I try to add another predicate, it does not work,
// it returns a list size of 0

query.select(widgetRoot).where(cb.and(
cb.equal(tagJoin.get(Tag_.value), "tom")),
cb.equal(tagJoin.get(Tag_.value), "harry"));

}

希望能够匹配所有或任何给定的标签,并认为这将是 cb.and() 或 cb.or() 的问题

我用谷歌搜索了一下,发现了一些链接,比如 collections ,还有this我认为这并不完全相关...我还浏览了 pdf jpa 文档, online user guide并且没有看到明确涵盖这一点。如果我错过了什么,请告诉我

另请注意,我需要匹配标签值,因为该字符串是标签 obj 的字段。

感谢您的帮助!!

感谢您的帮助

最佳答案

假设 Tag 上有一个 Widget 属性,如下所示:

@ManyToOne
private Widget widget;

如果您想匹配任何标签,您甚至不需要动态查询。与FluentJPA可以这样实现:

List<Object> tags; // passed as a parameter

FluentQuery query = FluentJPA.SQL((Widget w,
Tag tag) -> {
SELECT(DISTINCT(w));
FROM(w).JOIN(tag).ON(tag.getWidget() == w);
WHERE(tags.contains(tag.getTagValue()));
});

query.createQuery(getEntityManager(), Widget.class).getResultList();

如果您想匹配所有标签,则需要动态查询:

public List<Widget> filterWidgets(List<String> tags) {
Function1<Tag, Boolean> dynamicFilter = buildAnd(tags);

FluentQuery query = FluentJPA.SQL((Widget w,
Tag tag) -> {

SELECT(DISTINCT(w));
FROM(w).JOIN(tag).ON(tag.getWidget() == w);
WHERE(dynamicFilter.apply(tag));
});
return query.createQuery(getEntityManager(), Widget.class).getResultList();
}

private Function1<Tag, Boolean> buildAnd(List<String> tags) {
Function1<Tag, Boolean> criteria = Function1.TRUE();

for (String tag : tags)
criteria = criteria.and(t -> t.getTagValue() == parameter(tag));

return criteria;
}

使用 3 个标签,这是生成的查询:

SELECT DISTINCT t0.*  
FROM Widget t0 INNER JOIN Tag t1 ON (t1.widget_id = t0.id)
WHERE (((t1.tag_value = ?1) AND (t1.tag_value = ?2)) AND (t1.tag_value = ?3))

关于java - jpa条件查询,匹配作为参数传递的任何列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57452245/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com