#目的
・一覧画面にいい感じにページングしたい
・実装はなるべく簡単な方がいい
#環境
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
#実装
###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();
// 1ページに表示する最大件数を10件に
resolver.setMaxPageSize(10);
argumentResolvers.add(resolver);
}
}
###Repository
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) {
// 取得したentityをmodelに変換して返却
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)
<!-- ページャーのところだけです -->
<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>
#感想
Pageableを渡すことで簡単にページネーションが実装できました。
今回は取得したentityそのものをページネーションの対象としました。
今回の実装にあたり、取得したentityの1フィールドについてページネーションできれば、
殆ど既存のソースコードに変更を加えずに対応できたのですが、調べた限りそれは無理のようでした。