Spring Boot で Pagination

最近 Spring Boot をやっていて Pagination とかを試していてひと段落ついたのでメモ

前提として JPA 使用。

pagination をしたい時には基本的 repository に PagingAndSortingRepository を使う。

where と一緒に使いたい時には JpaSpecificationExecutor も使う。

Model

@Entity
@Table(name = "users")
public class User {

    @Id
    private Integer id;

    @Column
    private String name;

}

Repository

public interface UserRepository extends PagingAndSortingRepository<User, Integer>, JpaSpecificationExecutor<User> {
}

Service

@Service
public class UserService {

    private final UserRepository repository;

    public UserService(final UserRepository repository) {
        this.repository = repository;
    }

    public Page<User> search(Integer id, String name, Pageable pageable) {
        return repository.findAll(Specifications.where(idEquals(id)).and(nameEquals(name)), pageable);
    }

    private Specification<User> idEquals(Integer id) {
        if (id == null) {
            return null;
        }
        return (root, query, cb) -> cb.equals(root.get("id"), id);
    }

    private Specification<User> nameEquals(String name) {
        if (name == null || name.isEmpty()) {
            return null;
        }
        return (root, query, cb) -> cb.equals(root.get("name"), name);
    }

}

Controller

@Controller
@RequestMapping("users")
public class UserController {

    private final UserService service;

    public UserController(final UserService service) {
        this.service = service;
    }

    @GetMapping("")
    public String index(Model model, @RequestParam(value = "id", required = "required") Integer id, @RequestParam(value = "name", required = "required") String name, @Sort@PageableDefault(size = 20) Pageable pageable) {
        Page<User> users = service.search(id, name, pageable);
        model.addAttribute("id", id);
        model.addAttribute("name", name);
        model.addAttribute("users", users);
        return "users/index";
    }

}

Specification<T> を作成するところで null を返すと条件文を作成しない。

※参考

qiita.com