@Entity
@Getter
public class Article {
.....
@ManyToMany
private Set<SiteUser> voter;
@Column(columnDefinition = "integer default 0", nullable = false)
private int countView;
@Column(columnDefinition = "integer default 0", nullable = false)
private int voteCount;
}
JOIN과 COUNT()를 사용해서 값을 가져와야 하는데 컬럼을 추가하는 것이 사용성&성능면에서 더 낫다고 판단했음.public Page<Article> getArticleList(int page, int size) {
List<Sort.Order> orderList = new ArrayList<>();
orderList.add(Sort.Order.desc("createDate"));
Pageable pageable = PageRequest.of(page, size, Sort.by(orderList));
Page<Article> articlePage = articleRepository.findAll(pageable);
if (articlePage.getContent().isEmpty()) {
log.info("size : {}, page : {}", size, page);
throw new InvalidPageException(ERROR_PAGE_OUT_OF_ARTICLE_RANGE);
}
return articlePage;
}
↑ 기존 코드
createDate(작성일)만 담아서 정렬하고 있음.ORDER BY createDate DESC가 적용됨.↓ 수정한 코드
public Page<Article> getArticleList(int page, int size, String sortType) {
List<Sort.Order> orderList = new ArrayList<>();
switch (sortType) {
case "vote" -> orderList.add(Sort.Order.desc("voteCount"));
case "view" -> orderList.add(Sort.Order.desc("viewCount"));
default -> orderList.add(Sort.Order.desc("createDate"));
}
// 추천수 or 조회수가 같은 경우를 대비해서 두 번째 정렬 조건을 추가.
if (!("date".equals(sortType))) {
orderList.add(Sort.Order.desc("createDate"));
}
Pageable pageable = PageRequest.of(page, size, Sort.by(orderList));
Page<Article> articlePage = articleRepository.findAll(pageable);
if (articlePage.getContent().isEmpty()) {
log.warn("size : {}, page : {}", size, page);
throw new InvalidPageException(ERROR_PAGE_OUT_OF_ARTICLE_RANGE);
}
return articlePage;
}
List<Sort.Order>타입의 orderList를 만들고switch문을 통해 sortType의 값을 체크해서 orderList에 추가함.@RequestParam(value = "sortType", defaultValue = "date") String sortType
Model에 값을 담아줘야됨.model.addAttribute("sortType", sortType);
sortType에는 view로 되어 있음.
switch문을 지나오면 orderList에 값이 하나 들어오게 되고countView,DESC(내림차순)이 들어있는 것을 확인.
if문을 지나면createDate, DESC(내림차순)역시 들어와 있는 것을 확인할 수 있음.
Sort.by()로 인해 Sort클래스의 by()메서드가 호출되었고 매개변수인 orders에 값이 들어있고orders를 이용해서 Sort의 생성자를 호출.new Sort(orders) 이렇게 객체를 생성하게 됨.
List<Order> orders의 경우 Sort클래스의 멤버변수(필드)인 것을 확인.


<!-- 페이지당 글 수 선택 -->
<div class="d-flex justify-content-start mb-2">
<form th:action="@{/article/list}" method="get" class="d-flex align-items-center">
<!-- 페이지당 글 수 선택시 항상 첫 페이지(0) -->
<input type="hidden" name="page" value="0" />
<select id="sizeSelect" name="size" class="form-select w-auto" onchange="this.form.submit()">
<option th:value="10" th:selected="${size == 10}">10개씩</option>
<option th:value="20" th:selected="${size == 20}">20개씩</option>
<option th:value="40" th:selected="${size == 40}">40개씩</option>
<option th:value="50" th:selected="${size == 50}">50개씩</option>
</select>
</form>
</div>
↓ 변경
<form th:action="@{/article/list}" method="get" class="d-flex align-items-center gap-2 mb-3">
<input type="hidden" name="page" value="0" />
<label for="sizeSelect" class="fw-bold">페이지당:</label>
<select id="sizeSelect" name="size" class="form-select w-auto" onchange="this.form.submit()">
<option th:value="10" th:selected="${size == 10}">10개</option>
<option th:value="20" th:selected="${size == 20}">20개</option>
<option th:value="40" th:selected="${size == 40}">40개</option>
<option th:value="50" th:selected="${size == 50}">50개</option>
</select>
<label for="sortSelect" class="fw-bold">정렬:</label>
<select id="sortSelect" name="sortType" class="form-select w-auto" onchange="this.form.submit()">
<option th:value="date" th:selected="${sortType == 'date'}">최신순</option>
<option th:value="vote" th:selected="${sortType == 'vote'}">추천순</option>
<option th:value="view" th:selected="${sortType == 'view'}">조회순</option>
</select>
</form>
부트스트랩 select를 사용했음.

<input type="hidden" name="page" value="0" />
name속성의 값은 쿼리스트링(QueryString)으로 서버로 전송될 값임.
name속성에 맞게 @RequestParam에노테이션을 이용해서 이름을 맞춰줘야됨.@RequestParam(value = "sortType", defaultValue = "date") String sortTypeonchange="this.form.submit()
th:value
th:selected="${sortType == 'date'}"
date이면 해당 옵션이 선택 상태로 표시됨.Ex
/article/list?page=5&size=10&sortType=vote
sortType="vote"가 모델에 담겨서 반환될 경우<option value="vote" selected>추천순</option>