将可选参数传递给Spring Data Repository方法的@Query

时间:2017-08-16 14:55:06

标签: spring spring-data cypher spring-data-neo4j software-design

我在当前项目中使用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是否在这种情况下提供任何支持?

1 个答案:

答案 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();

我个人对其进行了修改,因此它没有使用“:”,因为它们对我的使用来说是多余的。

相关问题