gpt4 book ai didi

java - 使用 AND 运算符 CriteriaBuilder 的规范和谓词集合

转载 作者:行者123 更新时间:2023-12-01 12:45:36 25 4
gpt4 key购买 nike

为了从我的数据库中获取元素申请人的列表,当我尝试检索它们时遇到了问题。

我知道在这个例子中,我通过一个错误的方法来获取:获取实体的字符串 ID,但这需要重构;)

这是我的规范和带有连接的谓词循环:

public static Specification<Applicant> applicantsMatchMobility(final String... mobilities) {
return new Specification<Applicant>() {

@Override
public Predicate toPredicate(Root<Applicant> root, CriteriaQuery<?> query, CriteriaBuilder builder) {

Collection<Predicate> predicates = new ArrayList<>();

Join<Applicant, Mobility> applicantMobilityJoin = root.join("mobility");

for(String mobility : mobilities) {
predicates.add(builder.equal(applicantMobilityJoin.<Mobility>get("id"), Integer.parseInt(mobility)));
}

return builder.and(predicates.toArray(new Predicate[predicates.size()]));

}

};
}

当我只传递一个 Mobility 实体的 id 时,它工作得很好,但当它是一个字符串 ids 数组 > 1 时,它总是返回 0..

这是我的 junit 测试:

 @Test
public void ShouldHaveOneApplicantWhenSearchMobilityMultipleTotallyEquals(){

String mobilitiesId[] = {"0", "1"};
List<Applicant> applicantList = applicantRepository.findAll(applicantsMatchMobility(mobilitiesId));
Assert.assertNotNull(applicantList);
Assert.assertEquals("Result", 1, applicantList.size());

Applicant applicant = applicantList.get(0);
Assert.assertNotNull(applicant);
Assert.assertEquals("Result", "XBNC", applicant.getFirstName());

}

这是生成的请求:

select
*
from
applicant applicant0_
inner join
applicant_mobility mobility1_
on applicant0_.id=mobility1_.id_applicant
inner join
mobility mobility2_
on mobility1_.id_mobility=mobility2_.id
where
mobility2_.id=0
and mobility2_.id=1

这是我用于测试的数据集:

    <?xml version='1.0' encoding='UTF-8'?>
<dataset>
<MOBILITY ID="0" NAME="sud"/>
<MOBILITY ID="1" NAME="nice"/>
<MOBILITY ID="2" NAME="cannes"/>
<MOBILITY ID="3" NAME="nowhere"/>

<TAGS ID="0" NAME="tags1"/>
<TAGS ID="1" NAME="tags2"/>
<TAGS ID="2" NAME="tags3"/>

<STATUS ID="0" NAME="status1"/>
<STATUS ID="1" NAME="status2"/>

<AVAILABILITY ID="0" NAME="availability1"/>

<APPLICANT ID="0" LAST_NAME="XBNC" FIRST_NAME="XBNC" YEAR="2001" WAGE_CLAIM="50" ID_STATUS="0" ID_AVAILABILITY="0" />
<APPLICANT ID="1" LAST_NAME="XBN" FIRST_NAME="XBN" YEAR="0" WAGE_CLAIM="70" ID_STATUS="1" ID_AVAILABILITY="0"/>
<APPLICANT ID="2" LAST_NAME="MI" FIRST_NAME="MI" YEAR="1995" WAGE_CLAIM="0" ID_STATUS="1" ID_AVAILABILITY="0"/>
<APPLICANT ID="3" LAST_NAME="bisTronomique" FIRST_NAME="bisTronomique" YEAR="-400" WAGE_CLAIM="0" ID_STATUS="0" ID_AVAILABILITY="0"/>

<APPLICANT_MOBILITY ID_APPLICANT="0" ID_MOBILITY="0"/>
<APPLICANT_MOBILITY ID_APPLICANT="0" ID_MOBILITY="1"/>

<APPLICANT_MOBILITY ID_APPLICANT="1" ID_MOBILITY="0"/>
<APPLICANT_MOBILITY ID_APPLICANT="1" ID_MOBILITY="2"/>

<APPLICANT_MOBILITY ID_APPLICANT="2" ID_MOBILITY="1"/>

<APPLICANT_TAGS ID_APPLICANT="0" ID_TAGS="0"/>
<APPLICANT_TAGS ID_APPLICANT="0" ID_TAGS="1"/>
<APPLICANT_TAGS ID_APPLICANT="0" ID_TAGS="2"/>

</dataset>

您是否可以看到,在此测试中我只需要返回“XBNC”申请人,因为他包含 2 个相应的 MobilityeID ..

最佳答案

这是一个基本的 SQL 逻辑问题,我猜测您正在尝试检索与移动 ID 0 和 1 相对应的 2 行:当前代码中的 where 子句 (critria) 构建 [where id = '0' < b>and id = '1'],这将始终不返回任何行,因为特定表字段不能同时等于两个值。
而不是and() ,您需要使用or()方法,它将构建一个 where 子句,例如 [where id = '0' or id = '1']。假设恰好一行且一行仅将 movingID 设置为 1,并且一行且一行仅将 movingID 设置为 0,那么您应该从运行查询中获取两行。

更新:
编辑您的问题后,我想我可以看到您的问题所在。这仍然是一个 SQL 问题,但这意味着您的查询需要稍微复杂一些。您需要获取如下所示的查询:

select
*
from
applicant <b><i>applicant0_</i></b>
inner join
applicant_mobility mobility1_
on applicant0_.id=mobility1_.id_applicant
inner join
mobility mobility2_
on mobility1_.id_mobility=mobility2_.id
where
exists (
select * from applicant_mobility
where <b><i>id_applicant = applicant0_.id</i></b>
and id_mobility = 1;
)
and
exists (
select * from applicant_mobility
where <b><i>id_applicant = applicant0_.id</i></b>
and id_mobility = 0;
)

请注意 applicant 之间的连接和applicant_mobility在子查询中。这实际上是说:对于主查询找到的每个申请人实例,验证它是否位于一个集合中,其中至少有一个对应的移动性设置为 0 的申请人_mobility 实例,以及另一个移动性设置为 1 的实例。
因此,函数中的循环需要为提供的每个移动 ID 创建子查询,然后使用构建器 and()exists()将它们放在一起。

关于java - 使用 AND 运算符 CriteriaBuilder 的规范和谓词集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24727926/

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