通过多个可选参数过滤JPA存储库

时间:2018-01-05 20:56:26

标签: java spring-mvc spring-boot spring-data-jpa

我有一个简单的REST服务,它返回有大约20个字段的用户配置文件实体。

我需要实现一个功能来过滤需要姓氏的数据,但所有其他字段(名字,年龄,城市,州,邮政编码等)都是可选的。

有没有办法使用JpaRepository使用if而不为每个组合的patamenters创建大量else / if #available(iOS 11.0, *) { _fixedSpace.widthAnchor.constraint(equalToConstant: 280.0).isActive = true } 语句?

3 个答案:

答案 0 :(得分:0)

  • 总是最好返回一个实体的DTO表示 REST响应。
  • 在您的DTO中,您只能映射实体和必填字段 忽略其他可选参数。

查看http://www.baeldung.com/entity-to-and-from-dto-for-a-java-spring-application

答案 1 :(得分:0)

这是JPA criteria的用例(自JPA2起可用) 实际上,当您想要编写动态查询时,首先,您不希望对每个组合进行硬编码JPQL查询,并且您不希望连接JPQL的块,因为这是容易出错,在编译时没有检查。

请注意,在任何情况下(CriteriaJPQL),如果客户端已指定它可以在查询构建中考虑它们,则应检查每个可能的选项。

现在,在实现JPARepository接口时,您有两种方法:

  • 使用List<T> findAll(@Nullable Specification<T> spec);接口提供的JpaSpecificationExecutor,您也可以在自定义存储库中实现该接口。

  • 使用您自己的定义方法JPARepository的接口丰富findAll(),并将参数作为包含研究值的对象。
    然后创建一个具体的类来实现JPARepository
    您可以注入EntityManager并使用Criteria API。

答案 2 :(得分:0)

JpaRepository接口还实现了 QueryByExampleExecutor 接口,该接口提供了findAll方法来使用示例查询(QBE)技术获取数据。该方法确实适用于您的方案,并且当实体具有很多字段并且您希望用户能够通过某些字段过滤实体时,实际上是理想的选择。

假设实体是 Person ,并且您想创建一个端点来获取属性等于指定属性的人员。可以通过以下代码完成:

实体类:

@Entity
public class Person implements Serializable {
    private Long id;
    private String firstName;
    private String lastName;
    private Integer age;
    private String city;
    private String state;
    private String zipCode;
}

控制器类:

@Controller
public class PersonController {
    private PersonService service;
    private PersonController(PersonService service) {
        this.service = service;
    }

    @GetMapping
    public List<Person> getMatchingPersons(@RequestBody Person personFilter) {
        return service.findMatchingPersons(personFilter);
    }
}

服务类别:

@Service
public class PersonService {
    private PersonRepository repository;
    private PersonService(PersonRepository repository) {
        this.repository = repository;
    }

    public List<Person> getMatchingPersons(Person personFilter) {
        return repository.findAll(Example.of(personFilter));
    }
}

存储库类:

@Repository
public class PersonRepository implements JpaRepository<Person, Integer> {
}