【问题标题】:How to query same table with same parameter but with different where conditions and get combined result at last如何使用相同的参数但不同的where条件查询同一张表并最终获得组合结果
【发布时间】:2022-07-14 02:05:53
【问题描述】:

我有一个全局搜索,我将使用一个关键字进行搜索,但需要获得包含表中所有匹配列的结果。

Page<A> a = null;
a = zRepo.getResultByNameSearch(searchText)
a = zRepo.getResultByNumberSeach(searchText)
a = zRepo.getRsultByProjectSearch(searchText)

@Query("select * from a_table x where x.name like :searchText")
Page<A> getResultByNameSearch(@Param("searchText") String searchText, Pageable pageable);

@Query("select * from a_table where x.number like :searchText")
Page<A> getResultByNumberSearch(@Param("searchText") String searchText, Pageable pageable);

@Query("select * from a_table where x.project like :searchText")
Page<A> getResultByProjectSearch(@Param("searchText") String searchText, Pageable pageable);

所以每个存储库调用查询并获取同一个表,但根据 searchText

假设名称为“Company910” 让我们假设一个数字“XX910” 让我们假设一个项目“910”

现在我正在搜索“910”。所以最后我需要得到所有 3 个数据的结果。页面将包含 a_table 的所有列以及“Company910”、“XX910”、“910”的结果列表。

如何实现这一点,或者是否有任何其他方式可以维护单个查询,而不是名称、编号和项目的三个不同的查询。

【问题讨论】:

    标签: java mysql sql spring-boot jpa


    【解决方案1】:

    关于如何获得组合结果的第一部分。我会做这样的事情。

    • 按照您编写的方式创建存储库接口,但使用 spring data jpa 而不是原始查询
    • 每个方法调用的用户 CompletableFuture
    • 将结果组合成一个 dto
    • 返回这个组合结果
    @Repository
    public interface SampleDocumentRepository extends JpaRepository<SampleDocument, Integer> {
    
        Page<SampleDocument> findByNameContains(String name, Pageable pageable);
    
        Page<SampleDocument> findByNumberContains(String number, Pageable pageable);
    
        Page<SampleDocument> findByProjectContains(String project, Pageable pageable);
    }
    

    结果组合在一起的服务类

    @Service
    @AllArgsConstructor
    public class SampleDocumentService {
        private final SampleDocumentRepository repository;
    
    
        @Transactional(readOnly = true)
        public CompletableFuture<ResultDto> search(String query) {
            PageRequest page = PageRequest.of(0, 20);
            CompletableFuture<Page<SampleDocument>> nameSearch = CompletableFuture.supplyAsync(() -> repository.findByNameContains(query, page));
            CompletableFuture<Page<SampleDocument>> numberSearch = CompletableFuture.supplyAsync(() -> repository.findByNumberContains(query, page));
            CompletableFuture<Page<SampleDocument>> projectSearch = CompletableFuture.supplyAsync(() -> repository.findByProjectContains(query, page));
            return CompletableFuture.allOf(nameSearch, numberSearch, projectSearch)
                    .thenApply(unused -> new ResultDto(nameSearch.join(), numberSearch.join(), projectSearch.join()));
        }
        
    }
    

    然后是来自服务的调用

    @GetMapping("/search")
        public CompletableFuture<ResultDto> search(@RequestParam("query") String query) {
            return service.search(query);
        }
    

    使用您的查询参数调用

    http://localhost:8080/sample/search?query=hello
    

    回答第二部分,如果您想检查查询是否存在于任何列中,您可以编写 JPA 查询结合 Or 运算符,如下所示。

    Page<SampleDocument> findByNameContainsOrNumberContainsOrProjectContains(String name, String number, String project, Pageable pageable);
    

    调用者会是这样的

    @Transactional(readOnly = true)
        public CompletableFuture<ResultDto> searchAll(String query) {
            PageRequest page = PageRequest.of(0, 20);
            CompletableFuture<Page<SampleDocument>> nameSearch = CompletableFuture.supplyAsync(() ->
                    repository.findByNameContainsOrNumberContainsOrProjectContains(query, query, query, page));
            return CompletableFuture.allOf(nameSearch)
                    .thenApply(unused -> new ResultDto(nameSearch.join(), null, null));
        }
    

    如果您想将 Async 与 Spring Data 和 Completable 一起使用,请关注此link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 2015-04-09
      • 1970-01-01
      • 2020-08-18
      • 1970-01-01
      相关资源
      最近更新 更多