Written By : Nguyễn Văn Linh
Gmail : Linhthai130100@gmail.com
1.Giới Thiệu
Tìm hiểu cách yêu cầu và chỉ hiển thị một phần dữ liệu từ cơ sở dữ liệu bằng cách sử dụng phân trang và sắp xếp đầu vào cũng như tham số truy vấn trong các ứng dụng khởi động mùa xuân và dữ liệu mùa xuân.
Phân trang và sắp xếp chủ yếu là bắt buộc khi chúng tôi hiển thị dữ liệu miền ở định dạng bảng trong giao diện người dùng.
Phân trang bao gồm hai trường - kích thước trang và số trang . Việc sắp xếp được thực hiện trên một trường trong số nhiều trường trong bảng.
Link bài viết tham khảo:Pagination and Sorting using Spring Data JPA.
2. Thực thể Jpa
Trong bài đăng này, chúng tôi đang lấy ví dụ về EmployeeEntity
lớp học. Mỗi cá thể thực thể đại diện cho một bản ghi nhân viên trong cơ sở dữ liệu.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="TBL_EMPLOYEES")
public class EmployeeEntity {
@Id
@GeneratedValue
private Long id;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@Column(name="email", nullable=false, length=200)
private String email;
//Setters and getters
@Override
public String toString() {
return "EmployeeEntity [id=" + id + ", firstName=" + firstName +
", lastName=" + lastName + ", email=" + email + "]";
}
}
3. Tạo kho lưu trữ (Repository)
PagingAndSortingRepository
là một phần mở rộng CrudRepository
để cung cấp các phương thức bổ sung để truy xuất các thực thể bằng cách sử dụng phân trang và sắp xếp trừu tượng. Nó cung cấp hai phương pháp:
Page findAll (Pageable pageable) - trả về một Page trong các thực thể đáp ứng giới hạn phân trang được cung cấp trong Pageable đối tượng.
Lặp lại findAll (Sort sort) - trả về tất cả các thực thể được sắp xếp theo các tùy chọn đã cho. Không có phân trang nào được áp dụng ở đây.
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import com.howtodoinjava.demo.entity.EmployeeEntity;
@Repository
public interface EmployeeRepository
extends PagingAndSortingRepository<EmployeeEntity, Long> {
}
4. Chấp nhận các tham số phân trang và sắp xếp
Nói chung, các tham số phân trang và sắp xếp là tùy chọn và do đó, một phần của URL yêu cầu dưới dạng tham số truy vấn . Nếu bất kỳ API nào hỗ trợ phân trang và sắp xếp, LUÔN LUÔN cung cấp các giá trị mặc định cho các tham số của nó - sẽ được sử dụng khi khách hàng không chọn chỉ định bất kỳ tùy chọn phân trang hoặc sắp xếp nào.
Các giá trị phân trang và sắp xếp mặc định sẽ được ghi lại rõ ràng trong tài liệu API. Trong giao diện người dùng, các giá trị mặc định này có thể được đánh dấu bằng các màu riêng biệt.
Giá trị số trang bắt đầu bằng 0. Vì vậy, trong giao diện người dùng, nếu bạn đang hiển thị số trang từ 1, thì đừng quên trừ ‘1’ trong khi tìm nạp bản ghi.
Trong bộ điều khiển mvc mùa xuân bên dưới , chúng tôi đang chấp nhận các tham số phân trang và sắp xếp bằng cách sử dụng các tham số truy vấn pageNo
, pageSize
và sortBy
. Ngoài ra, theo mặc định, '10’nhân viên sẽ được tìm nạp từ cơ sở dữ liệu theo số trang '0’và hồ sơ nhân viên sẽ được sắp xếp dựa trên 'id’trường.
Ở đây , Số lượng trang bắt đầu từ 0 :
@RestController
@RequestMapping("/employees")
public class EmployeeController
{
@Autowired
EmployeeService service;
@GetMapping
public ResponseEntity<List<EmployeeEntity>> getAllEmployees(
@RequestParam(defaultValue = "0") Integer pageNo,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(defaultValue = "id") String sortBy)
{
List<EmployeeEntity> list = service.getAllEmployees(pageNo, pageSize, sortBy);
return new ResponseEntity<List<EmployeeEntity>>(list, new HttpHeaders(), HttpStatus.OK);
}
}
Để thực hiện phân trang và / hoặc sắp xếp, chúng ta phải tạo org.springframework.data.domain.Pageable
hoặc org.springframework.data.domain.Sort
các thể hiện được chuyển cho findAll()
phương thức.
@Service
public class EmployeeService
{
@Autowired
EmployeeRepository repository;
public List<EmployeeEntity> getAllEmployees(Integer pageNo, Integer pageSize, String sortBy)
{
Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by(sortBy));
Page<EmployeeEntity> pagedResult = repository.findAll(paging);
if(pagedResult.hasContent()) {
return pagedResult.getContent();
} else {
return new ArrayList<EmployeeEntity>();
}
}
}
5. Kỹ thuật phân trang và sắp xếp
5.1 Phân trang không phân loại
Để chỉ áp dụng phân trang trong tập kết quả, chúng ta sẽ tạo Pageable
đối tượng mà không có bất kỳ Sort
thông tin nào.
Pageable paging = PageRequest.of(pageNo, pageSize);
Page<EmployeeEntity> pagedResult = repository.findAll(paging);
5.2 Phân trang có sắp xếp
Để chỉ áp dụng phân trang trong tập kết quả, chúng ta sẽ tạo Pageable
đối tượng vớiSort
tên cột mong muốn.
Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by("email"));
Page<EmployeeEntity> pagedResult = repository.findAll(paging);
Theo mặc định, các bản ghi được sắp xếp theo thứ tự MONG MUỐN . Để chọn đơn đặt hàng ASCENDING
, hãy sử dụng .ascending()
phương pháp.
Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by("email").ascending());
Page<EmployeeEntity> pagedResult = repository.findAll(paging);
5.3 Chỉ phân loại
Nếu không cần trang và chỉ cần phân loại, chúng ta có thể tạo Sortđối tượng cho việc đó.
Sort sortOrder = Sort.by("email");
List<EmployeeEntity> list = repository.findAll(sortOrder);
Nếu chúng ta muốn áp dụng sắp xếp trên nhiều cột hoặc nhóm theo cách sắp xếp , thì điều đó cũng có thể thực hiện được bằng Sortcách sử dụng các bước mẫu trình tạo đơn giản.
Sort emailSort = Sort.by("email");
Sort firstNameSort = Sort.by("first_name");
Sort groupBySort = emailSort.and(firstNameSort);
List<EmployeeEntity> list = repository.findAll(groupBySort);
6. Sự khác biệt giữa Page và Slice
6.1 Page
Phương findAll(Pageable pageable)
thức này theo mặc định trả về một Page
đối tượng. Một Page
đối tượng cung cấp rất nhiều thông tin hữu ích khác ngoài danh sách nhân viên trong trang hiện tại.
Ví dụ: Một Page
đối tượng có tổng số trang , số trang current page
và cũng như xem trang hiện tại là trang đầu tiên hay trang cuối cùng.
Việc tìm tổng số trang sẽ gọi thêm một truy vấn count ()
gây ra thêm chi phí. Hãy chắc chắn khi bạn đang sử dụng nó.
Trong bài viết này sẽ giới thiệu mô tả và các thức hoạt động của Pagination and Sorting , mọi người có thể đọc bài viết và tìm hiểu thêm
6.2 Slice
Slice
rất giống với Page
, ngoại trừ nó không cung cấp tổng số trang trong cơ sở dữ liệu. Nó giúp cải thiện hiệu suất khi chúng tôi không cần hiển thị tổng số trang trong giao diện người dùng.
Nói chung, Slice
được sử dụng trong trường hợp điều hướng bao gồm các liên kết Trang tiếp theo và Trang trước .
Để sử dụng Slice, chúng tôi đã triển khai các phương pháp tùy chỉnh của riêng mình.
public interface EmployeeRepository extends CrudRepository<EmployeeEntity, Long>
{
public Slice<EmployeeEntity> findByFirstName(String firstName, Pageable pageable);
}
Hãy nhớ rằng chúng tôi sử dụng PagingAndSortingRepository
, kiểu trả về mặc định là Page
.
Pageable paging = PageRequest.of(pageNo, pageSize, Sort.by("email").descending());
Slice<EmployeeEntity> slicedResult = repository.findByFirstName("alex", paging);
List<EmployeeEntity> employeeList = slicedResult.getContent();
7. Bản demo phân trang và phân loại khởi động mùa xuân
Trong bản trình diễn này, số trang mặc định là 0, kích thước trang là 10 và cột sắp xếp mặc định là ‘id’.
Bây giờ gọi từng URL này một và quan sát kết quả đầu ra.
- http: // localhost: 8080 / staff? pageSize = 5
- http: // localhost: 8080 / staff? pageSize = 5 & pageNo = 1
- http: // localhost: 8080 / staff? pageSize = 5 & pageNo = 2
- http: // localhost: 8080 / staff? pageSize = 5 & pageNo = 1 & sortBy = email
- http: // localhost: 8080 / staff? pageSize = 5 & pageNo = 1 & sortBy = firstName
8. Kết thúc
Trên đấy là hướng dẫn và một số ví dụ về việc phân trang và sắp xếp trong spring data jpa . Hãy đọc thật kỹ và làm theo ví dụ mẫu
Chúc các bạn học tốt
Bình luận