[SPRING] 스프링 데이터의 페이지 매김 JPA (한계 및 오프셋)
SPRING스프링 데이터의 페이지 매김 JPA (한계 및 오프셋)
사용자가 내 쿼리 메서드에서 제한 (반환되는 크기의 크기) 및 오프셋 (반환 된 첫 번째 레코드 / 인덱스)을 지정할 수있게하려고합니다.
다음은 페이징 기능이없는 클래스입니다. 내 사업체 :
@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 () 메서드. 하지만 Employee 저장소 인터페이스를 사용하기 때문에이 방법을 사용할 수 없습니다. (또는 실제로 entityManager를 통해 쿼리를 정의하는 것이 더 낫습니까?) 어쨌든 entityManager를 사용하지 않고 오프셋을 지정하는 방법이 있습니까? 미리 감사드립니다.
해결법
-
==============================
1.아래 코드는 그렇게해야합니다. 나는 내 프로젝트에서 사용하고 대부분의 경우를 테스트했다.
아래 코드는 그렇게해야합니다. 나는 내 프로젝트에서 사용하고 대부분의 경우를 테스트했다.
용법:
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, new Sort(Sort.Direction.ASC,"id")); } @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(); } }
-
==============================
2.자신의 Pageable을 작성하여이를 수행 할 수 있습니다.
자신의 Pageable을 작성하여이를 수행 할 수 있습니다.
이 기본 샘플을 사용해보십시오. 나를 위해 잘 작동합니다.
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; } }
-
==============================
3.어쩌면 그 대답은 좀 늦을 지 모르지만 나는 똑같은 생각을했습니다. 오프셋 및 제한을 기준으로 현재 페이지를 계산합니다. 오프셋은 제한의 배수라고 "가정"하기 때문에 정확하게 동일하지는 않지만 응용 프로그램이 이에 적합 할 수 있습니다.
어쩌면 그 대답은 좀 늦을 지 모르지만 나는 똑같은 생각을했습니다. 오프셋 및 제한을 기준으로 현재 페이지를 계산합니다. 오프셋은 제한의 배수라고 "가정"하기 때문에 정확하게 동일하지는 않지만 응용 프로그램이 이에 적합 할 수 있습니다.
@Override public List<Employee> findByName(String name, int offset, int limit) { // limit != 0 ;) int page = offset / limit; return repository.findByName(name, new PageRequest(page, limit); }
나는 건축의 변화를 제안 할 것이다. 컨트롤러를 변경하거나 처음에는 가능한 한 페이지 및 제한을 제공하도록 서비스를 호출하는 모든 것을 변경하십시오.
-
==============================
4.스프링 데이터 jpa로는이 작업을 수행 할 수 없습니다. 오프셋이 매우 작은 경우 검색 후 쿼리에서 상위 X 문을 제거하면됩니다.
스프링 데이터 jpa로는이 작업을 수행 할 수 없습니다. 오프셋이 매우 작은 경우 검색 후 쿼리에서 상위 X 문을 제거하면됩니다.
그렇지 않으면 페이지 크기를 오프셋으로 정의하고 페이지 + 1에서 시작할 수 있습니다.
-
==============================
5.여기 있습니다 :
여기 있습니다 :
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); }
-
==============================
6.시도해보십시오 :
시도해보십시오 :
public interface ContactRepository extends JpaRepository<Contact, Long> { @Query(value = "Select c.* from contacts c where c.username is not null order by c.id asc limit ?1, ?2 ", nativeQuery = true) List<Contact> findContacts(int offset, int limit); }
-
==============================
7.같은 시간에 필터링 및 정렬 및 페이징을한다고 가정하십시오. @Query가 당신을 도울 것입니다.
같은 시간에 필터링 및 정렬 및 페이징을한다고 가정하십시오. @Query가 당신을 도울 것입니다.
@Query(value = "SELECT * FROM table WHERE firstname= ?1 or lastname= ?2 or age= ?3 or city= ?4 or " + " ORDER BY date DESC OFFSET ?8 ROWS FETCH NEXT ?9 ROWS ONLY" , nativeQuery = true) List<JobVacancy> filterJobVacancyByParams(final String firstname, final String lastname, final String age, final float city,int offset, int limit);
from https://stackoverflow.com/questions/25008472/pagination-in-spring-data-jpa-limit-and-offset by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 왜 Spring Integration에는 여러 XML 스키마가 있으며 어떤 스키마를 사용해야합니까? (0) | 2019.02.23 |
---|---|
[SPRING] 버블 부팅을 지원하는 gradle 연속 빌드가 있습니까? (0) | 2019.02.23 |
[SPRING] 찾을 수없는 'org.hibernate.SessionFactory'유형의 bean이 필요합니다. (0) | 2019.02.23 |
[SPRING] 스프링 레스트 컨트롤러 : 유효성을 선택적으로 끄는 방법 (0) | 2019.02.23 |
[SPRING] access_token : spring boot Oauth2로 리소스에 액세스 할 수 없습니다. (0) | 2019.02.23 |