当前位置: 首页 > 知识库问答 >
问题:

spring JPA-在代码中使用多个findby方法

车嘉实
2023-03-14

我在我的rdbms系统的顶部有spring boot的基础API,我做所有的操作,但是当它是关于从系统中选择数据时,我的GET映射endpoint有许多检查来决定我应该调用哪个findbyAttributes方法。

我创建了多个存储库方法,如findbyId、findbyIdAndName、findByIdandNameAndAge。

但是考虑一下我的场景,我在表中有大约30列,最终用户可能希望在某个时间点使用我的GETendpoint查询这些列,我已经实现了这一点,但是由于对我的实体的每个列/属性的请求数量不断增加,我的代码认知复杂性增加了很多。

我知道除了在多个if-else循环后面调用每个findby方法之外,还必须有一些不同的方法,我想这太糟糕了。

我的代码现在是这样的-

public Page<myEntity> getDataFromDatabase(
      @RequestParam(value = "id", required = false, defaultValue = "NA") String id,
      @RequestParam(value = "name", required = false, defaultValue = "NA") String name,
      @RequestParam(value = "age", required = false, defaultValue = "NA") String age,
      @RequestParam(value = "address", required = false, defaultValue = "NA") String address,
      Pageable pageable) {

    Page<myEntity> finalData = null;

    if (!id.equals("NA")
        && name.equals("NA")
        && age.equals("NA")
        && address.equals("NA")) {
      finalData = service.findById(id, pageable);

    } else if (id.equals("NA")
        && !name.equals("NA")
        && age.equals("NA")
        && address.equals("NA")) {
      finalData = service.findByName(name, pageable);
    } else if (id.equals("NA")
        && name.equals("NA")
        && !age.equals("NA")
        && address.equals("NA")) {
      finalData = service.findByAge(age, pageable);
    } else if (id.equals("NA")
        && name.equals("NA")
        && age.equals("NA")
        && !address.equals("NA")) {
      finalData = service.findByAddress(address, pageable);
    }else if (!id.equals("NA")
        && !name.equals("NA")
        && !age.equals("NA")
        && !address.equals("NA")) {
      finalData = service.findByIdAndNameAndAgeAndAddress(id,name,age,address, pageable);
    }else if (!id.equals("NA")
        && !name.equals("NA")
        && age.equals("NA")
        && address.equals("NA")) {
      finalData = service.findByIdAndName(id,name, pageable);
    }
    // few more else if as new column is being added
    // I think I did it but this will not last for long 

}

理解我是否要根据提到的条件逻辑添加所有findBy属性。

如果有人能帮上忙,我的一天就会光彩照人。

注意-我读过关于Jpa规范的文章,在这里,它们就像findAll方法逻辑一样,与多个规范进行映射,这与我每次需要创建特定条件库时调用每个get方法的感觉是一样的。

另外,请让我知道这是否是正确的方法,我的想法是用最佳实践编写更少的代码,这样从GETendpoint可以通过框架调用所有的JpaRepository findby方法,而不需要编写多个if-else。

共有1个答案

边明煦
2023-03-14

您确实应该考虑一下Jpa规范,这可能是最好的解决方案。用这种方法构建规范将会很容易,即使是30个属性。

您也可以检查Hibernate查询

首先创建如下所示的方法

 public Specification<MyEntity>  myEntitySpecification(String id, String name) {
         return (root, criteriaQuery, criteriaBuilder) -> {

            List<Predicate> predicateList  = new ArrayList<>();
            if (!id.equals("NA")){
                predicateList.add(criteriaBuilder.equal(root.get("id"), id));
            }
            if (!name.equals("NA")){
                predicateList.add(criteriaBuilder.equal(root.get("name"), name));
            }

            return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
        };
    }

那就叫它


    public Page<MyEntity> getDataFromDatabase(
            @RequestParam(value = "id", required = false, defaultValue = "NA") String id,
            @RequestParam(value = "name", required = false, defaultValue = "NA") String name,
            @RequestParam(value = "age", required = false, defaultValue = "NA") String age,
            @RequestParam(value = "address", required = false, defaultValue = "NA") String address,
            Pageable pageable) {



        Page<MyEntity> finalData = testRepository.findAll(myEntitySpecification(id, name), pageable);

return finalData ;
}
 类似资料:
  • 问题内容: 我有一个使用一些临时属性foo的域类。现在,我想在此属性上使用listOrderByFoo,但出现错误“无法解析属性:foo”。有什么方法可以在listOrderByProperty()或findByProperty()中使用瞬态属性吗? 问题答案: 抱歉不行。就像Matt在对您的问题的评论中说的那样,由于这些字段被标记为临时字段,因此它们不会持久保存到数据库中,因此您无法查询它们。如

  • 我想通过LoginBean设置我的User对象仅一次。然后我想通过CDI在其他@ManagedBean中重用它的setters、getters和一个方法。 我可以在每个需要loggedInUser的支持Bean中列出一个Bean。这似乎是错误的,因为我在每节课上都要复制粘贴两行 我可以使用。这允许我有一个方法来检索超类中的Bean实例,但这似乎也是错误的。也就是说,如果我无法找到纯CDI解决方案,

  • 我有一个负载平衡器,我想测试负载平衡器的性能。我使用Apache JMeter来测试负载平衡器。我需要更改我的IP地址,以便客户端IP总是不同的。我的uni不允许我添加多个IP地址(IP欺骗/ IP别名)。 所以,另一个选择是使用代理服务器。有没有办法一次在JMeter中使用2个或多个代理服务器?目前我只能一次指定一个代理服务器。 有办法扭转局面吗?

  • 我的代码结构如下: 事件 消息 其他代码 功能测试 在jacoco的构建脚本中,首先它必须复制所有类并使用该类目录来运行该工具。您能描述一下在这里编写目标目录的步骤吗。我的意思是,我应该如何提及运行代码覆盖的目录。 构建时,每个文件夹都有自己的目标文件夹,其中包含类。 以下是步骤: 在詹金斯将项目作为工作进行构建 将其部署到用户阶段 在詹金斯中运行雅各布报告作业 雅高报告工作说明: > 构建步骤-

  • 问题内容: 我有一个这样的实体类: 如何使用crudrepository spring数据jpa 编写以下查询的方法? 我期望像下面这样的spring data jpa方法,但是如何构造它呢? 我想在单个数据库命中中获取电子邮件列表。 问题答案: 以下签名将起作用: Spring Data JPA支持大量关键字来构建查询。并在其中。