在JPA进行分页查询时,Query接口中的啥方法用于设定需要获取的总行数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在JPA进行分页查询时,Query接口中的啥方法用于设定需要获取的总行数相关的知识,希望对你有一定的参考价值。

在JPA进行分页查询时,Query接口中的什么方法用于设定需要获取的总行数。急求

参考技术A 在hibernate的query接口查询出一个list后
list里有两个方法
list.setFirstResult(int a);
list.setMaxSize(int a);
第一个方法用来设置当前页要显示的第一条记录是从哪一个记录开始的
第二个方法用来设置每页的最大记录数
通过这个就足以实现分页了,先实现了功能再说吧,这样做反正是不太好呵呵

春季数据 jpa @query 和可分页

【中文标题】春季数据 jpa @query 和可分页【英文标题】:spring data jpa @query and pageable 【发布时间】:2014-04-16 04:58:41 【问题描述】:

我正在使用 Spring Data JPA,当我使用 @Query 来定义查询没有 Pageable 时,它可以工作:

public interface UrnMappingRepository extends JpaRepository<UrnMapping, Long> 
    @Query(value = "select * from internal_uddi where urn like %?1% or contact like %?1%", 
           nativeQuery = true)
    List<UrnMapping> fullTextSearch(String text);

但是如果我添加第二个参数Pageable@Query 将不起作用,Spring 将解析方法的名称,然后抛出 异常 No property full found。这是一个错误吗?

public interface UrnMappingRepository extends JpaRepository<UrnMapping, Long> 
    @Query(value = "select * from internal_uddi where urn like %?1% or contact like %?1%",
           nativeQuery = true)
    Page<UrnMapping> fullTextSearch(String text, Pageable pageable);

【问题讨论】:

【参考方案1】:

将您的查询重写为:

select iu from internal_uddi iu where iu.urn.... 

描述:http://forum.spring.io/forum/spring-projects/data/126415-is-it-possible-to-use-query-and-pageable?p=611398#post611398

【讨论】:

【参考方案2】:

类似的问题是asked on the Spring forums,其中指出要应用分页,必须派生第二个子查询。因为子查询引用相同的字段,所以您需要确保您的查询对其引用的实体/表使用别名。这意味着你写的地方:

select * from internal_uddi where urn like

你应该有:

select * from internal_uddi iu where iu.urn like ...

【讨论】:

不幸的是,这不适用于本机查询。不知道是否可以通过原生查询来实现? 如果你想写原生查询,那么你显然需要自己写查询来做分页。【参考方案3】:

考虑到UrnMapping 类映射到internal_uddi 表,我建议这样做:

@Repository
public interface UrnMappingRepository extends JpaRepository<UrnMapping, Long> 

    @Query(value = "select iu from UrnMapping iu where iu.urn like %:text% or iu.contact like %:text%")
    Page<UrnMapping> fullTextSearch(@Param("text") String text, Pageable pageable);

请注意,您可能必须关闭带有动态请求的本机查询。

【讨论】:

【参考方案4】:

您可以将分页与本机查询一起使用。它记录在这里:Spring Data JPA - Reference Documentation

"但是,您可以通过自己指定计数查询来使用本机查询进行分页: 示例 59. 使用 @Query"

在查询方法中声明用于分页的本机计数查询
public interface UserRepository extends JpaRepository<User, Long> 

  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
  Page<User> findByLastname(String lastname, Pageable pageable);

【讨论】:

countQuery 也适用于 non-native 查询,其中 Spring 无法从原始查询中导出元素的数量。 在 Spring Data JPA 文档中向下滚动到 Example 64. Declare native count queries for pagination at the query method by using @Query。【参考方案5】:

如果您使用的是 Spring Data JPA 2.0.4 及更高版本,请参考:Spring Data JPA @Query。示例如下:

@Query(value = "SELECT u FROM User u ORDER BY id")
Page<User> findAllUsersWithPagination(Pageable pageable);

【讨论】:

【参考方案6】:

我发现它在不同的jpa版本之间工作方式不同,为了调试,你最好添加这个配置来显示生成的sql,它会节省你很多时间!

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

对于spring boot 2.1.6.RELEASE,效果很好!

Sort sort = new Sort(Sort.Direction.DESC, "column_name");
int pageNumber = 3, pageSize = 5;
Pageable pageable = PageRequest.of(pageNumber - 1, pageSize, sort);
@Query(value = "select * from integrity_score_view " +
        "where (?1 is null or data_hour >= ?1 ) " +
        "and (?2 is null or data_hour <= ?2 ) " +
        "and (?3 is null or ?3 = '' or park_no = ?3 ) " +
        "group by park_name, data_hour ",
        countQuery = "select count(*) from integrity_score_view " +
                "where (?1 is null or data_hour >= ?1 ) " +
                "and (?2 is null or data_hour <= ?2 ) " +
                "and (?3 is null or ?3 = '' or park_no = ?3 ) " +
                "group by park_name, data_hour",
        nativeQuery = true
)
Page<IntegrityScoreView> queryParkView(Date from, Date to, String parkNo, Pageable pageable);

你不要写order bylimit,它会生成正确的sql

【讨论】:

【参考方案7】:

使用 @Query ,我们也可以在需要在 JPA 方法末尾传递 Pageable 类的对象的地方使用分页

例如:

Pageable pageableRequest = new PageRequest(page, size, Sort.Direction.DESC, rollNo);

在哪里, page = 页面索引(索引从零开始) 大小 = 记录数 Sort.Direction = 按 rollNo 排序 rollNo = 用户类中的字段

UserRepository repo
repo.findByFirstname("John", pageableRequest);

public interface UserRepository extends JpaRepository<User, Long> 

  @Query(value = "SELECT * FROM USER WHERE FIRSTNAME = :firstname)
  Page<User> findByLastname(@Param("firstname") String firstname, Pageable pageable);

【讨论】:

【参考方案8】:

使用@Query在查询方法处声明本机计数查询以进行分页

public interface UserRepository extends JpaRepository<User, Long> 

  @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
  countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
  nativeQuery = true)
  Page<User> findByLastname(String lastname, Pageable pageable);


希望对你有帮助

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods

【讨论】:

【参考方案9】:

我尝试了上述所有解决方案,但都不起作用,最后我从分页中删除了排序并且它起作用了

【讨论】:

【参考方案10】:

我遇到了同样的问题 - 没有 Pageable 方法可以正常工作。 当作为方法参数添加时 - 不起作用。

在使用 DB 控制台和本机查询支持后,决定该方法按应有的方式工作。但是,仅适用于大写字母。 我的应用程序的逻辑是所有names 的实体都以大写字母开头。

玩一点。并发现方法名称处的IgnoreCase 具有“魔法”作用,这是可行的解决方案:

public interface EmployeeRepository 
                            extends PagingAndSortingRepository<Employee, Integer> 

    Page<Employee> findAllByNameIgnoreCaseStartsWith(String name, Pageable pageable);


实体的样子:

@Data
@Entity
@Table(name = "tblEmployees")
public class Employee 

    @Id
    @Column(name = "empID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @NotEmpty
    @Size(min = 2, max = 20)
    @Column(name = "empName", length = 25)
    private String name;

    @Column(name = "empActive")
    private Boolean active;

    @ManyToOne
    @JoinColumn(name = "emp_dpID")
    private Department department;

【讨论】:

我怎样才能做到这一点,但我有一个视图而不是一个实体。我想查询视图但不想编写本机 SQL,因为 LIKE 参数未转义(带有 %、~* 等)【参考方案11】:

以下教程帮助了我 -> https://www.baeldung.com/spring-data-jpa-query

此时 4.3. Spring Data JPA 2.0.4 之前的版本

添加\ n-- #pageable \ n 非常重要 没有这个我错了

另外分页设置必须是无序的

PageRequest paginaConf = new PageRequest ((param1 - 1)
                                                 , param2);

终于要转换Page

  Page <Object []> list = myQueryofRepo ();
         List <XXXModel> lstReturn = myConversor (list.getContent ());
         Page <XXXModel> ret = new PageImpl <XXXModel> (lstReturn, pageConf, param2);

【讨论】:

【参考方案12】:

当使用具有 (nativeQuery = true) 的 nativeQuery 时,您可以通过添加 (LIMIT :sizeValue OFFSET :page) 在查询中自己进行分页

注意: 您传递给此方法的页面值应为 offset * size

例子

 @Query(value = "SELECT * FROM person " +    
                   "LIMIT ?1 OFFSET ?2", nativeQuery = true)
    Optional<List<TDriverJob>> findPersons(int size, int page);

【讨论】:

以上是关于在JPA进行分页查询时,Query接口中的啥方法用于设定需要获取的总行数的主要内容,如果未能解决你的问题,请参考以下文章

JPA分页查询怎么做

Android用query怎么进行多条件查询?

带有分页的 Spring Data JPA 方法查询给了我一个错误

spring data jpa 分页查询

jpa分页

JPA自定义模糊查询并将查询结果分页