【问题标题】:How to get results of JPA custom query as Page如何将 JPA 自定义查询的结果作为页面获取
【发布时间】:2020-11-14 02:17:15
【问题描述】:

我有一个存储库,它返回 Page<Mind>:

public interface MindRepository extends PagingAndSortingRepository<Mind, Integer> {
    Page<Mind> findByCountry(String country, Pageable pageable);
}

还有一个使用它的控制器:

private MindRepository mindRepository;

@GetMapping(path = "/minds", produces = "application/json")
public Page<Mind> getMinds(String country, Integer page, Integer size) {
    Pageable pageable = PageRequest.of(page,size);
    return mindRepository.findByCountry(country,pageable);        
}

一切正常。控制器以适合 FrontEnd 的 json 格式返回 Page&lt;Mind&gt;

但现在我必须使查询更复杂,有几个过滤器,动态变化。我想像这样使用createQuery

public interface CustomizedMindRepository<T> {
    Page<T> findByCountry(String country, Pageable pageable);
}

public interface MindRepository extends PagingAndSortingRepository<Mind, Integer>,CustomizedMindRepository {
    Page<Mind> findByCountry(String country, Pageable pageable);
}

public class CustomizedMindRepositoryImpl implements CustomizedMindRepository {
    @PersistenceContext
    private EntityManager em;

    @Override
    public Page<Mind> findByCountry(String country, Pageable pageable) {
        return em.createQuery("from minds where <dynamical filter> AND <another dynamical filter> AND <...etc>", Mind.class)
                .getResultList();
    }
}

但是getResultList() 返回List,而不是Page :(

最好的解决方法是什么?

【问题讨论】:

  • 你试过link吗?
  • @ruba 谢谢!它必须工作。但由于某些原因,原生 SQL 现在更适合我,所以我正在尝试 Kavithakaran 方式。
  • 如果您启用 Spring data web 支持扩展和 QueryDSL 扩展,您将获得所有这些(即排序、过滤(按动态标准)和页面),而无需编写任何代码。 stackoverflow.com/questions/59027999/…

标签: java spring jpa orm pagination


【解决方案1】:
  • 页面存储库调用执行两个调用,一个用于获取结果,另一个用于获取总大小。因此,您还必须通过执行计数查询来复制该行为
    @Override
    public Page<Mind> findByCountry(String country, Pageable pageable) {
        long offset = pageable.getPageNumber() * pageable.getPageSize();
        long limit = pageable.getPageSize();
        
        List<Item> itemsInNextPage = em.createQuery(query)
                .setFirstResult(offset)
                .setMaxResults(limit)
                .getResultList();
        
        long total = // Another query to get the total count
                
        List<Mind>  results = em.createQuery("from minds ...", Mind.class)
                             .getResultList();
        return new PageImpl(results, pageable, total); 
                            
    }

【讨论】:

    【解决方案2】:

    如果你想使用EntityManager.createQuery,你可以使用setFirstResultsetMaxResults方法来达到同样的效果。

    @Override
    public List<Mind> findByCountry(String country, Pageable pageable) {
      return em.createQuery("from minds where <dynamical filter> AND <another dynamical filter> AND <...etc>", Mind.class)
               .setFirstResult(startPosition)
               .setMaxResults(size)
               .getResultList();
    }
    

    在这种情况下size 与您的情况具有相同的含义,但startPosition 不是page,而是计算为:

    startPosition = page * size
    

    但是,如果您需要构建动态查询 - 考虑使用 Specifications 或 JPA Criteria API。

    【讨论】:

    • 它返回List&lt;Mind&gt;。但是FrontEnd想要的不是纯List,而是json中的所有分页信息
    猜你喜欢
    • 2013-12-03
    • 2012-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 2011-07-24
    • 2023-03-22
    相关资源
    最近更新 更多