STACKJAVA

Code ví dụ Spring Boot Data JPA – Page/Pageable – Sort

Code ví dụ Spring Boot Data JPA – Page/Pageable – Sort

(Xem lại: Hướng dẫn phân trang, sắp xếp trong Spring Data JPA )

Các công nghệ sử dụng:

Tạo Database

Tạo database spring-data với table customer trên MySQL

CREATE DATABASE  IF NOT EXISTS `spring-data`;
USE `spring-data`;

DROP TABLE IF EXISTS `customer`;
CREATE TABLE `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

Tạo Spring Boot Project

Cấu trúc project:

File application.properties

Config các thông tin kết nối database, hibernate.

## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/spring-data?useSSL=false
spring.datasource.username=root
spring.datasource.password=admin1234

## ==============JPA / HIBERNATE=================
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect


File entity

package stackjava.com.sbdatapagination.entities;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "customer")
public class Customer implements Serializable{
  private static final long serialVersionUID = 1L;

  @Id
  @Column(name = "id")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @Column(name = "name")
  private String name;

  @Column(name = "address")
  private String address;

  // getter - setter
}

File Repository

package stackjava.com.sbdatapagination.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import stackjava.com.sbdatapagination.entities.Customer;

@Repository
public interface CustomerRepository extends JpaRepository<Customer, Integer> {

  @Query("SELECT e FROM Customer e")
  Page<Customer> findCustomers(Pageable pageable);
}

File Controller.java

package stackjava.com.sbdatapagination.controller;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import stackjava.com.sbdatapagination.entities.Customer;
import stackjava.com.sbdatapagination.repository.CustomerRepository;

@Controller
public class CustomerController {

  @Autowired
  private CustomerRepository customerRepository;

  @PostConstruct
  public void initData() {
    System.out.println("__________Reset and init data________________");
     customerRepository.deleteAll();
     for (int i = 0; i < 100; i++) {
     customerRepository.save(new Customer("name" + i, "address" + i));
     }
  }

  @RequestMapping("/")
  public String listCustomer(Model model,
      @RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
      @RequestParam(name = "size", required = false, defaultValue = "5") Integer size,
      @RequestParam(name = "sort", required = false, defaultValue = "ASC") String sort) {
    Sort sortable = null;
    if (sort.equals("ASC")) {
      sortable = Sort.by("id").ascending();
    }
    if (sort.equals("DESC")) {
      sortable = Sort.by("id").descending();
    }
    Pageable pageable = PageRequest.of(page, size, sortable);
    
    model.addAttribute("listCustomer", customerRepository.findCustomers(pageable));
    return "customer-list";
  }

}

– Method initData được đánh dấu @PostConstruct tức là nó chỉ chạy duy nhất 1 lần khi bean CustomerController được khởi tạo; method initData sẽ thực hiện khởi tạo data (xóa hết dữ liệu trong database và insert vào 100 đối tượng customer)

– method listCustomersẽ thực hiện trả về trang customer-list.html với các đối tượng được truy vấn theo tham số gửi lên (trang nào, số phần tử là bao nhiêu, sắp xếp theo thứ tự nào) – ở đây mình thực hiện sort theo id.

File view

<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Data Paging + Sorting</title>
<style>
table, th, td, tr {
  border: 1px solid black;
}

td {
  padding-right: 30px;
}
</style>
</head>
<body>
  <h1>Demo Spring Boot + Spring Data Paging / Sorting</h1>
  <table>
    <tr>
      <th>Id</th>
      <th>Name</th>
      <th>Address</th>
    </tr>
    <th:block th:each="customer : ${listCustomer}">
      <tr>
        <td><p th:text="${customer.id}"></p></td>
        <td><p th:text="${customer.name}"></p></td>
        <td><p th:text="${customer.address}"></p></td>
      </tr>
    </th:block>
  </table>

</body>
</html>

Demo:

Trường hợp không truyền gì lên thì sẽ mặc định lấy page đầu tiên (page 0) và kích thước page là 5

Trường hợp mình truyền page = 2, kích thước page = 10 => số phần tử được lấy là 10 kể từ phần tử thứ 10 (page đầu tiên có 10 phần tử)

Okay, Done!

Download code ví dụ trên tại đây.

 

References:

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/