spring data jpa @query和pageable

时间:2014-03-12 07:48:56

标签: java spring hibernate jpa spring-data-jpa

我正在使用Spring Data JPA,当我使用@Query来定义查询 WITHOUT Pageable时,它可以正常运行:< / p>

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);
}

12 个答案:

答案 0 :(得分:33)

您可以对原生查询使用分页。这里记录了:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#_native_queries

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

在查询方法中声明分页的本机计数查询
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);
}

答案 1 :(得分:28)

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

select * from internal_uddi where urn like

你应该改为:

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

答案 2 :(得分:8)

考虑到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);
}

请注意,您可能必须使用动态请求关闭本机查询。

答案 3 :(得分: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

答案 4 :(得分:1)

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

在使用数据库控制台和本机查询支持之后,我们决定该方法的工作原理与预期相同。但是,仅适用于 大写字母
我的应用程序的逻辑是,实体的所有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;
}

答案 5 :(得分:0)

如果您使用的是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 :(得分:0)

我发现在不同的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 :(得分:0)

使用@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 :(得分:0)

使用@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 :(得分:0)

我尝试了上述所有解决方案,但均无济于事,最后我从分页中删除了Sorting并成功了

答案 10 :(得分:0)

以下教程帮助了我 -> 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);

答案 11 :(得分:0)

当使用具有 (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);