我希望用户能够在我的查询方法中指定限制(返回量的大小)和偏移量(返回的第一条记录/返回的索引)。
这里是我没有任何分页功能的类。我的实体:
@Entity
public Employee {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="NAME")
private String name;
//getters and setters
}
我的仓库:
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
@Query("SELECT e FROM Employee e WHERE e.name LIKE :name ORDER BY e.id")
public List<Employee> findByName(@Param("name") String name);
}
我的服务界面:
public interface EmployeeService {
public List<Employee> findByName(String name);
}
我的服务实施:
public class EmployeeServiceImpl {
@Resource
EmployeeRepository repository;
@Override
public List<Employee> findByName(String name) {
return repository.findByName(name);
}
}
现在,我尝试提供支持偏移和限制的分页功能。我的实体类保持不变。
我的“新”存储库接受一个可分页的参数:
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
@Query("SELECT e FROM Employee e WHERE e.name LIKE :name ORDER BY e.id")
public List<Employee> findByName(@Param("name") String name, Pageable pageable);
}
我的“新”服务接口包含两个附加参数:
public interface EmployeeService {
public List<Employee> findByName(String name, int offset, int limit);
}
我的“新”服务实现:
public class EmployeeServiceImpl {
@Resource
EmployeeRepository repository;
@Override
public List<Employee> findByName(String name, int offset, int limit) {
return repository.findByName(name, new PageRequest(offset, limit);
}
}
然而,这不是我想要的。PageRequest指定页面和大小(页面和页面大小)。现在指定大小正是我想要的,但是,我不想指定起始页,我希望用户能够指定起始记录/索引。我想要类似的东西
public List<Employee> findByName(String name, int offset, int limit) {
TypedQuery<Employee> query = entityManager.createQuery("SELECT e FROM Employee e WHERE e.name LIKE :name ORDER BY e.id", Employee.class);
query.setFirstResult(offset);
query.setMaxResults(limit);
return query.getResultList();
}
特别是setFirstResult()和setMaxResult()方法。但是我不能使用这个方法,因为我想使用员工存储库接口。或者通过entityManager定义查询实际上更好?)不管怎样,有没有一种方法可以在不使用entityManager的情况下指定偏移量?提前感谢!
给你:
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
@Query(value="SELECT e FROM Employee e WHERE e.name LIKE ?1 ORDER BY e.id offset ?2 limit ?3", nativeQuery = true)
public List<Employee> findByNameAndMore(String name, int offset, int limit);
}
您可以通过创建自己的页面来实现这一点。
试试这个基本样本。对我来说很好:
public class ChunkRequest implements Pageable {
private int limit = 0;
private int offset = 0;
public ChunkRequest(int skip, int offset) {
if (skip < 0)
throw new IllegalArgumentException("Skip must not be less than zero!");
if (offset < 0)
throw new IllegalArgumentException("Offset must not be less than zero!");
this.limit = offset;
this.offset = skip;
}
@Override
public int getPageNumber() {
return 0;
}
@Override
public int getPageSize() {
return limit;
}
@Override
public int getOffset() {
return offset;
}
@Override
public Sort getSort() {
return null;
}
@Override
public Pageable next() {
return null;
}
@Override
public Pageable previousOrFirst() {
return this;
}
@Override
public Pageable first() {
return this;
}
@Override
public boolean hasPrevious() {
return false;
}
}
下面的代码应该可以做到。我在自己的项目中使用,并对大多数情况进行了测试。
使用方法:
Pageable pageable = new OffsetBasedPageRequest(offset, limit);
return this.dataServices.findAllInclusive(pageable);
和源代码:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.springframework.data.domain.AbstractPageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import java.io.Serializable;
/**
* Created by Ergin
**/
public class OffsetBasedPageRequest implements Pageable, Serializable {
private static final long serialVersionUID = -25822477129613575L;
private int limit;
private int offset;
private final Sort sort;
/**
* Creates a new {@link OffsetBasedPageRequest} with sort parameters applied.
*
* @param offset zero-based offset.
* @param limit the size of the elements to be returned.
* @param sort can be {@literal null}.
*/
public OffsetBasedPageRequest(int offset, int limit, Sort sort) {
if (offset < 0) {
throw new IllegalArgumentException("Offset index must not be less than zero!");
}
if (limit < 1) {
throw new IllegalArgumentException("Limit must not be less than one!");
}
this.limit = limit;
this.offset = offset;
this.sort = sort;
}
/**
* Creates a new {@link OffsetBasedPageRequest} with sort parameters applied.
*
* @param offset zero-based offset.
* @param limit the size of the elements to be returned.
* @param direction the direction of the {@link Sort} to be specified, can be {@literal null}.
* @param properties the properties to sort by, must not be {@literal null} or empty.
*/
public OffsetBasedPageRequest(int offset, int limit, Sort.Direction direction, String... properties) {
this(offset, limit, new Sort(direction, properties));
}
/**
* Creates a new {@link OffsetBasedPageRequest} with sort parameters applied.
*
* @param offset zero-based offset.
* @param limit the size of the elements to be returned.
*/
public OffsetBasedPageRequest(int offset, int limit) {
this(offset, limit, Sort.unsorted());
}
@Override
public int getPageNumber() {
return offset / limit;
}
@Override
public int getPageSize() {
return limit;
}
@Override
public int getOffset() {
return offset;
}
@Override
public Sort getSort() {
return sort;
}
@Override
public Pageable next() {
return new OffsetBasedPageRequest(getOffset() + getPageSize(), getPageSize(), getSort());
}
public OffsetBasedPageRequest previous() {
return hasPrevious() ? new OffsetBasedPageRequest(getOffset() - getPageSize(), getPageSize(), getSort()) : this;
}
@Override
public Pageable previousOrFirst() {
return hasPrevious() ? previous() : first();
}
@Override
public Pageable first() {
return new OffsetBasedPageRequest(0, getPageSize(), getSort());
}
@Override
public boolean hasPrevious() {
return offset > limit;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof OffsetBasedPageRequest)) return false;
OffsetBasedPageRequest that = (OffsetBasedPageRequest) o;
return new EqualsBuilder()
.append(limit, that.limit)
.append(offset, that.offset)
.append(sort, that.sort)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(limit)
.append(offset)
.append(sort)
.toHashCode();
}
@Override
public String toString() {
return new ToStringBuilder(this)
.append("limit", limit)
.append("offset", offset)
.append("sort", sort)
.toString();
}
}
问题内容: 当调用支持它们的外部数据资源时,AngularJS是否具有Limit和Offset请求方法? 我想象有一个比这更优雅的解决方案,我通过routeParams传递限制和偏移量: 问题答案: 完整的分页解决方案是:(1)与服务器/数据库进行通信的服务;(2)处理next / prev的指令;以及(3)将其粘合在一起的控制器。 一旦有了指令和服务,您的控制器就是这样简单: 使用同样简单的HT
我得到了存储库代码: 当我在该查询上运行测试时,我得到了以下Hibernate警告:
问题内容: 我正在使用Spring Data JPA,当我用来定义一个 WITHOUT 的查询时,它可以工作: 但是,如果我添加第二个参数,则将无法正常工作,Spring将解析该方法的名称,然后抛出 异常 。这是错误吗? 问题答案: 在Spring论坛上提出了一个类似的问题,指出要应用分页,必须派生第二个子查询。因为子查询引用的是相同的字段,所以您需要确保查询对引用的实体/表使用别名。这意味着您在
我有一个简单的JpaRepository和一个finder,它返回按名为“number”的属性降序排列的记录。“number”属性也是我的实体的@Id。这很好,但是有数千条记录,所以我想返回一个页面而不是列表。 如果我将查找器更改为以下内容,则排序不再起作用。我尝试过使用可分页参数的排序功能,但不起作用。还删除了OrderByNumberDesc,但结果相同。 EDIT-添加控制器方法 以下是我的
我正在开发一个jQuery分页工具,当我让分页工作时,我看到了一个缺陷: 在桌面上有一行14个分页链接是可以的,但在移动设备上是不行的。因此,我想将一次可见页面的数量限制为5个(不包括next/prev按钮),并在到达第三个可见页面时进行更新,并更新分页中的可见页面 到目前为止,我已经编写了这个CodePen。我知道有插件可以为我做这件事,但我想避免在这个项目中使用插件。 HTML(正在分页的示例
我在Spring boot版本1.3.6中使用Spring Data JPA。 null 这将返回父实体,而不是子实体。 知道怎么做吗?