如何使用属性表达式编写JPA存储库方法,以检查列表中是否存在多个项目或这些项目的属性?我可以在列表中查找单个项目,请参阅下面的邮政编码,但我试图编写一种检查多个邮政编码的方法,其中结果集中的每个人在其地址列表中都有两个邮政编码。
@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
// Works
Set<Person> findAllByAddresses_ZipCode(String zip);
// Doesn't work - does not return expected results
Set<Person> findAllByAddresses_ZipCode_And_Addresses_ZipCode(String zip1, String zip2);
}
我目前的hack是为2个邮政编码取两套,然后找到两套的交集:
public @ResponseBody
Iterable<Person> personsWithBothZipCodes(@PathVariable("zip1") String zip1,
@PathVariable("zip2") String zip2) {
Set<Person> a = personRepository.findAllByAddresses_ZipCode(zip1);
Set<Person> b = personRepository.findAllByAddresses_ZipCode(zip2);
// Only return results that contain both zip1 and zip2.
a.retainAll(b);
return a;
}
该实体如下所示:
@Entity
public class Person
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
// zipcode is a String property on an Address.
@OneToMany(targetEntity = com.data.Address.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Address> addresses = new ArrayList<Address>();
...
}
有没有办法把它写成方法标题的一部分? Relevant docs
答案 0 :(得分:2)
是的,只需在查询中添加In
字样
Set<Person> findAllByAddresses_ZipCodeIn(Set<String> zip);
然后在您的控制器中,您可以执行以下操作:
public @ResponseBody Iterable<Person> personsWithBothZipCodes(@PathVariable("zip1") String zip1, @PathVariable("zip2") String zip2) {
Set<String> zipSet = new HashSet<>();
zipSet.add(zip1);
zipSet.add(zip2);
Set<Person> a = personRepository.findAllByAddresses_ZipCodeIn(zipSet);
return a;
}
不知道这是否有效,但可以尝试
Set<Person> findAllByAddresses_ZipCodeInAndZipCodeIn(Set<String> zip1, Set<String> zip2);
public @ResponseBody Iterable<Person> personsWithBothZipCodes(@PathVariable("zip1") String zip1, @PathVariable("zip2") String zip2) {
Set<String> zipSet1 = new HashSet<>();
zipSet1.add(zip1);
Set<String> zipSet2 = new HashSet<>();
zipSet2.add(zip2);
Set<Person> a = personRepository.findAllByAddresses_ZipCodeInAndZipCodeIn(zipSet1, zipSet2);
return a;
}
答案 1 :(得分:1)
也许您可以使用JPQL查询(如评论中所示)?
@Query("from Person as person" +
" join person.addresses as address1 with address1.zipCode = ?1" +
" join person.addresses as address2 with address2.zipCode = ?2")
Set<Person> findByZipCodes(String zipCode1, String zipCode2);
没有真正复制你的案子,但它应该可行。