首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从SpringJpa ExampleMatcher获得的从大多数匹配到最少用于高级搜索的排序ExampleMatcher

问从SpringJpa ExampleMatcher获得的从大多数匹配到最少用于高级搜索的排序ExampleMatcher
EN

Stack Overflow用户
提问于 2020-05-01 08:02:56
回答 1查看 226关注 0票数 0

我正在为图书管理系统编写一个高级搜索函数,使用Spring和MySQL。

“我的书”对象包含各种信息,如material id,book name, author, publisher, description, product type (如故事书或参考材料等)。

我设法编写了一个ExampleMatcher,如下所示;

代码语言:javascript
复制
ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny().
                withIgnoreCase()
                .withIgnorePaths("material_id")
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withStringMatcher(ExampleMatcher.StringMatcher.STARTING)
                .withIgnoreNullValues();

Example example = Example.of(book, exampleMatcher);

List<Book> all = bookRepository.findAll(example);

但是当我得到结果集时,结果会根据material id进行排序。而且,几乎所有字段都具有匹配属性的记录也在那里,但是根据id进行排序。

是否有一种方法可以对结果进行排序,即最匹配的记录在列表中的前几个记录中,然后是其他记录?从大多数匹配到最小匹配排序?

据我所知,JpaSort允许升序和降序排序,也可以允许对特定属性进行特定排序。但是在高级搜索中,搜索是根据用户填写的属性动态进行的。因此,我不能编程表的哪些字段排序正确?例如,如果我将按升序排序的图书名称字段编程,如果用户没有为该特定字段指定任何值,那么在该字段下排序是无用的,对吗?

这就是为什么我想知道是否有任何方法动态排序结果从大多数匹配到最少匹配。任何完成这一任务的方法都是非常感谢的。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-02 07:59:11

在互联网上阅读了50到70多篇文章和帖子两天之后,我能够以一种更优化的方式实现高级搜索。

我没有能够找到如何排序从大多数匹配到最不匹配的结果,正如我最初在问题中所问的那样。所以如果有人还能回答我原来的问题,我很乐意接受。

我使用的解决方法如下所示。从我动态生成SQL查询的想法出发,我找到了一条线索,并引用了有关这方面的文章。

在Spring的动态查询中,作者使用Java手动遍历实体类的非空字段并生成SQL查询。但是我们都知道,当您使用Springboot时,以及当所有配置都由Springboot为您完成时,我认为这并不是一种有效的方法,可以显式地使用Hibernate依赖项、管理会话和运行SQL查询。现在不再推荐上面文章中使用的HibernateJpaSessionFactoryBean。因此,我引用了各种文章和Spring文档,但无法解决我一直认为Springboot找不到entityManagerFactory bean的错误。

因此,我寻找使用Spring本身动态生成查询的方法,而不是使用Hibernate,并且在会话管理等方面面临麻烦。带有Spring数据JPA规范的动态查询和使用Spring数据JPA规范有足够的关于如何实现JpaSpecification的信息,以便在Springboot中动态生成查询。

最后,我使用了这里列出的所有这3篇文章中的信息来提出我的实现。我使用Java反射根据实体对象中非空字段的类类型创建规范。

我自己添加的新部分是,我将所有独立的规范组合到一个列表中,并编写了一个循环来动态生成用于检索数据的最终规范。详情如下。

代码语言:javascript
复制
    List<BookSpecification> bookSpecifications = createDynamicQuery(book);
    if (bookSpecifications.size() != 0) {
        Specification<Book> dynamicQuery = Specification.where(bookSpecifications.get(0));

        for (int i = 1; i < bookSpecifications.size(); i++) {
            dynamicQuery = dynamicQuery.or(bookSpecifications.get(i));
        }

        List<Book> all = bookRepository.findAll(dynamicQuery);
        all.forEach(System.out::println);

        return all;
    }

上面我以我自己的方式使用的createDynamicQuery()方法是从引用的文章中的信息中得到灵感的。

使用这种方法,我能够获得更精确的高级搜索结果,而不是使用ExampleMatcher对相同的高级搜索标准。而且,由于我是根据特定的字段名进行搜索,所以搜索结果也是以一种精确的方式排序的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61538828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档