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

在spring数据jpa存储库中通过许多可选参数进行搜索

漆雕深
2023-03-14

所以我有表注释和作者。我想用许多可选参数构建复杂的搜索栏。我想用可选的作者名字/姓氏和一些标志来过滤评论,比如人气(基于评论评级)。

由于我不知道如何使用spring数据jpa存储库编写它,我一直在考虑使用@query注释将其编写为本机查询,像这样的smth应该可以工作

Select c.* from comment c join author a on a.id = c.author_id
Where (:firstname = '' or (:firstname = a.firstname)) 
And (:lastname = '' or (:lastname = a.lastname))
And (:popular = false or (c.rating > 25))

是否有使用Spring data jpa编写它的选项?

例如,将来我计划添加更多参数和分页。使用Spring就像使用sql查询1分钟,我会损失几个小时。

在这种情况下是否有一些最佳实践?

共有2个答案

洪飞扬
2023-03-14

您可以使用jpa或criteriabuilder,如果您喜欢使用jpa,可以这样做:

@Query("select s from SomeEntity s "
        + "where (s.description is null or s.description = :description) "
        + "and (s.name is null or s.name = :name) "
List<SomeEntity> find(String description, String name);
易俊驰
2023-03-14

我建议使用JpaSpecificationExecutor存储库方法findAll(规范

实体:

@Entity
@Table(name = "author")
public class Author {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @Column(name = "firstname")
    String firstname ;

    @Column(name = "lastname")
    String lastname ;

    // getters, setters, equals, hashcode, toString ...
}

@Entity
@Table(name = "comment")
public class Comment {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @ManyToOne
    @JoinColumn(name = "author_id")
    Author author;

    @Column(name = "rating")
    Integer rating;

    // getters, setters, equals, hashcode, toString ...
}

存储库:

@Repository
public interface CommentRepository 
    extends JpaRepository<Comment, Long>, JpaSpecificationExecutor<Comment> {

}

规格:<代码>组织。springframework。数据jpa。领域规范

public class CommentSpecs {

      /** if firstname == null then specification is ignored */
      public static Specification<Comment> authorFirstnameEquals(String firstname) {
        return (root, query, builder) -> 
             firstname == null ? 
                 builder.conjunction() :
                 builder.equal(root.get("author").get("firstname"), firstname);
      }

      /** if lastname == null then specification is ignored */
      public static Specification<Comment> authorLastnameEquals(String lastname) {
        return (root, query, builder) -> 
             lastname == null ? 
                 builder.conjunction() :
                 builder.equal(root.get("author").get("lastname"), lastname);
      }

      /** if rating == null then specification is ignored */
      public static Specification<Comment> ratingGreaterThan(Integer rating) {
        return (root, query, builder) -> 
             rating == null ? 
                 builder.conjunction() :
                 builder.greaterThan(root.get("rating"), rating);
      }
}

服务方式参数:

public class CommentParameters {

  String authorFirstname;
  String authorLastname;
  Integer rating;

  // getters, setters

}

所有参数都可以为空。您只能设置您需要的参数。如果参数为空,我们的规范将忽略它

服务:

@Service
public class CommentService {

  @Autowired
  CommentRepository repository;
                
  public List<Comment> getComments(CommentParameters params, Pageable pageable) {

      Specification spec1 = CommentSpecs.authorFirstnameEquals(params.getAuthorFirstname());                                            
      Specification spec2 = CommentSpecs.authorLastnameEquals(params.getAuthorLastname());
      Specification spec3 = CommentSpecs.ratingGreaterThan(params.getRating());

      Specification spec = Specifications.where(spec1).or(spec2).or(spec3);
                                                                    
      return repository.findAll(spec, pageable);

   }
}

我使用文本编辑器编写了代码,因此需要修改。但我认为要点很容易发现

 类似资料:
  • 是否有一种方法可以使用来完成这一任务,而不需要为每个Patamenter组合创建大量/语句?

  • 对于方法,如果我发送空白,它可以工作,但值为null。而且,要搜索的字段太多了。所以我正在寻找一种更好的方法来搜索这样的表单。在Grails框架中,我可以为此创建名称,但在中没有找到更好的方法。 有什么想法吗?谢了。

  • 是否有一种方法可以使通用Spring数据JPA存储库正确处理类似的方法?例如只返回狗,而不返回所有动物?或者至少,最好的变通方法是什么? 它的工作几乎完美,保存每一个动物在自己的桌子上,等等。唯一的问题是:同时返回水豚和狗。这个答案解释说: 这只有在域类使用单表继承时才起作用。我们在引导时能得到的关于domain类的唯一信息是它将是Product对象。因此,对于像findAll()甚至findBy

  • 我读过一些关于在存储库请求中使用空值的帖子,但它们都已经存在多年了。所以我问这个问题是为了了解问题的现状。 我想说的是: 我想要一个带有可选空值的JPA请求。我的存储库中的函数如下所示: 这样我就可以像这样省略过滤器中的参数:(@Query的一部分) 这只在我的参数不为NULL时有效。 请注意,我在这里使用的是原生查询。(JPA实现是Hibernate,DB是postgres) 提前感谢您的每一次

  • 它是否将其存储在缓存中?我有一个应用程序,但应用程序中没有任何地方。属性是提到的db详细信息。我可以通过邮递员存储数据和查询它。

  • 问题内容: 我试图在一个小型独立应用程序中一起使用spring数据和spring config。 1. 我的问题是如何在不使用Spring的情况下发现spring数据存储库 通过spring config? 2. 如果没有,我可以以某种方式一起使用“ ClassPathXmlApplicationContext”和“ AnnotationConfigApplicationContext”吗? 问题