Implement pagination using SpringData Pageable + Thymeleaf

Purpose

・ I want to page the list screen nicely ・ Implementation should be as easy as possible

environment

SpringBoot 2.1.0.RELEASE Spring Data Commons 2.1.2.RELEASE https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Pageable.html

Implementation

Configuration


import org.springframework.context.annotation.Configuration;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyAppWebConfig implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(
            List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
        //Maximum number of items displayed on one page is increased to 10
        resolver.setMaxPageSize(10);
        argumentResolvers.add(resolver);
    }
}

Repository I used JPA.


import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MyHistoryRepository
        extends PagingAndSortingRepository<MyHistory, Long> {

    Page<MyHistory> findByUserIdAndDeletedFalse(
            String userId, Pageable pageable);

}

Service


@Service
@Transactional(readOnly = true)
public class MyHistoryServiceImpl implements MyHistoryService {

    @Autowired
    MyHistoryRepository myHistoryRepository;

    public Page<MyHistoryModel> getMyHistoryByUserId(
            String userId, Pageable pageable) {
        //Convert the acquired entity to model and return it
        return myHistoryRepository
                .findByUserIdAndDeletedFalse(userId,
                        pageable)
                .map(MyHistoryConverter::entityToModel);
    }
}

Controller


@Controller
@RequestMapping("/mypage")
public class MypageController {

    @Autowired
    MyHistoryService myHistoryService;

    @GetMapping
    public String doGetMypage(@AuthenticationPrincipal MyUserDetails user,
            Model model, Pageable pageable) {
        model.addAttribute("myHistory", myHistoryService
                .getMyHistoryByUserId(user.getUserId(), pageable));
        return "view";
    }
}

View(Thymeleaf)

<!--Only at the pager-->
<div th:unless="${myHistory.getContent().size()==0}" th:fragment='paginationbar'>
		<ul>
			<li th:class="${myHistory.first} ? 'disabled':''" style="display:inline">
				<span th:if="${myHistory.first}">first</span>
				<a th:if="${not myHistory.first}" th:href="@{${'/mypage'}(page=0)}">first</a>
			</li>
			<li th:each='i : ${#numbers.sequence(0, myHistory.totalPages-1)}' th:class="(${i}==${myHistory.number})? 'active' : ''" style="display:inline">
		<span th:if='${i}==${myHistory.number}' th:text='${i+1}'>1</span>
			<a th:if='${i}!=${myHistory.number}' th:href="@{${'/mypage'}(page=${i})}">
				<span th:text='${i+1}'>1</span>
			</a>
		</li>
		<li th:class="${myHistory.last} ? 'disabled':''" style="display:inline">
			<span th:if="${myHistory.last}">last</span>
			<a th:if="${not myHistory.last}" th:href="@{${'/mypage'}(page=(${myHistory.totalPages}-1))}">last</a>
		</li>
	</ul>
</div>

Impressions

I was able to easily implement pagination by passing Pageable. This time, the acquired entity itself was targeted for pagination. In this implementation, if pagination can be done for one field of acquired entity, I was able to handle it with almost no changes to the existing source code, but as far as I investigated, it seemed impossible.

Recommended Posts

Implement pagination using SpringData Pageable + Thymeleaf
Implement Rails pagination
Implement ProgressBar using library
[Swift] Implement UITableView using xib