spring data jpa @query 和可分页

问题描述 投票:0回答:14

我正在使用 Spring Data JPA,当我使用

@Query
定义查询 WITHOUT
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);
}
java spring hibernate jpa spring-data-jpa
14个回答
102
投票

您可以将分页与本机查询结合使用。它记录在此处:Spring Data JPA - 参考文档

但是,您可以通过自己指定计数查询来使用本机查询进行分页: 示例 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);
}


15
投票
考虑到

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

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


14
投票
使用 @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); }
    

6
投票
如果您使用的是 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);
    

2
投票
将您的查询重写为:

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
投票
我发现它在不同的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 by

limit
,它会生成正确的sql


2
投票
使用@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


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

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

1
投票
对我来说,Pageable 的返回类型不起作用,但将返回类型更改为 List 或Optional

工作正常。

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); // this doesnt work, for this you need to use countQuery List<UrnMapping> fullTextSearch(String text, Pageable pageable); // this is working }
    

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


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 <Object []> list = myQueryofRepo (); List <XXXModel> lstReturn = myConversor (list.getContent ()); Page <XXXModel> ret = new PageImpl <XXXModel> (lstReturn, pageConf, param2);
    
这困扰了我一段时间,但我找到了一个非常顺利的解决方案。

挑战是 JPA 无法自动检测计数查询,因此我决定使用

countName

,根据 JPA 文档
Returns the name of the javax.persistence.NamedQuery to be used to execute count queries when pagination is used. Will default to the named query name configured suffixed by .count.

所以我创建了一个命名查询

@NamedNativeQuery( name = "[queryName].count", query = [your count query], resultSetMapping = "[query resultSetMapping name]" ) }
如图所示,计数查询应带有 

.count

 后缀

Count 查询返回

Long

,因此将 resultSetMapping 添加为

@SqlResultSetMapping( name="[query resultSetMapping name]", columns={@ColumnResult(name="count", type = Long.class)})
然后在您的存储库中,使用如下所示的计数查询

@Query(countName ="[queryName].count" , nativeQuery = true) Page<Object> [mainQuery](...params)
希望这有帮助!


0
投票
这困扰了我一段时间,但我找到了一个非常顺利的解决方案。

挑战是 JPA 无法自动检测计数查询,因此我决定使用

countName

,根据 JPA 文档
Returns the name of the javax.persistence.NamedQuery to be used to execute count queries when pagination is used. Will default to the named query name configured suffixed by .count.

所以我创建了一个命名查询

@NamedNativeQuery( name = "[queryName].count", query = [your count query], resultSetMapping = "[query resultSetMapping name]" ) }
如图所示,计数查询应带有 

.count

 后缀

Count 查询返回

Long

,因此将 resultSetMapping 添加为

@SqlResultSetMapping( name="[query resultSetMapping name]", columns={@ColumnResult(name="count", type = Long.class)})
然后在您的存储库中,使用如下所示的计数查询

@Query(countName ="[queryName].count" , nativeQuery = true) Page<Object> [mainQuery](...params)
希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.