我在当前项目中使用Spring Data和Neo4j,并且遇到以下情况:
@RestController
@RequestMapping(value = SearchResource.URI)
public class PersonResource {
public static final String URI = "/person";
@Autowired
PersonRepository personRepository;
@GetMapping
public Collection<Person> findPersons(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "birthDate", required = false) Long birthDate,
@RequestParam(value = "town", required = false) Spring town) {
Collection<Person> persons;
if (name != null && birthDate == null && town == null) {
persons = personRepository.findPersonByName(name);
} else if (name != null && birthDate != null && town == null {
persons = personRepository.findPersonByNameAndBirthDate(name, birthDate);
} else if (name != null && birthDate != null && town != null {
persons = personRepository.findPersonByNameAndBirthDateAndTown(name, birthDate, town);
} else if (name == null && birthDate != null && town == null {
persons = findPersonByBirthDate(birthDate);
} else if
...
}
return persons;
}
}
您可能已经可以看到我的问题:if-else-blocks链。每次我添加一个新的过滤器来搜索人员时,我都要添加新的可选参数,将所有if-else-blocks加倍,并将新的find-Methods添加到我的PersonRepository中。所有find-Methods都使用Spring @Query注释进行注释,并获取自定义cypher查询以获取数据。
是否有可能以更优雅的方式实现此功能? Spring Data是否在这种情况下提供任何支持?
答案 0 :(得分:1)
我使用带有Spring Data的QueryDSL解决了这个问题。
关于baeldung.com有一个很好的教程。
使用QueryDSL,您的spring数据查询只是personRepository.findAll(predicate);
。
您可以使用对象来表示多个请求参数,并将其类型声明为Optional<String> name;
等。
然后你可以构建谓词(假设你在链接教程中设置了东西):
Predicate predicate = new MyPredicateBuilder().with("name", ":", name.orElse(""))
.with("birthDate", ":", birthDate.orElse(""))
.with("town", ":", town.orElse(""))
.build();
我个人对其进行了修改,因此它没有使用“:”,因为它们对我的使用来说是多余的。