我正在使用 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);
}
您可以将分页与本机查询结合使用。它记录在此处: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);
}
在 Spring 论坛上提出了类似的问题,其中指出要应用分页,必须派生第二个子查询。由于子查询引用相同的字段,因此您需要确保查询对其引用的实体/表使用别名。这意味着你写的地方:
select * from internal_uddi where urn like
您应该:
select * from internal_uddi iu where iu.urn like ...
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);
}
请注意,您可能必须关闭带有动态请求的本机查询。
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);
}
Spring Data JPA @Query。示例如下:
@Query(value = "SELECT u FROM User u ORDER BY id")
Page<User> findAllUsersWithPagination(Pageable pageable);
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
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
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;
}
注意: 传递给此方法的页面值应为 offset * size
示例
@Query(value = "SELECT * FROM person " +
"LIMIT ?1 OFFSET ?2", nativeQuery = true)
Optional<List<TDriverJob>> findPersons(int size, int page);
工作正常。
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
}
挑战是 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
Long
,因此将 resultSetMapping 添加为
@SqlResultSetMapping(
name="[query resultSetMapping name]",
columns={@ColumnResult(name="count", type = Long.class)})
然后在您的存储库中,使用如下所示的计数查询
@Query(countName ="[queryName].count" , nativeQuery = true)
Page<Object> [mainQuery](...params)
希望这有帮助!