2023-11-13 작성

스프링부트 개발환경 구성하기 (8) 동적 정렬처리

 

포스팅 순서는 아래와 같다.

 

동적으로 정렬 처리하기

이전 포스팅에서는 Pageable을 이용하여 페이징을 구현해보았다. 이번에는 좀 더 응용해서 등록일자 기준으로 동적으로 정렬 처리를 해보자.

BoardController.java

package com.company.helloBoard.domain.board.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.data.web.SortDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.company.helloBoard.domain.board.model.Board;
import com.company.helloBoard.domain.board.service.BoardService;

@RestController
@RequestMapping(value = "/boards")
public class BoardController {

	@Autowired
	BoardService boardService;

	@GetMapping("")
	public ResponseEntity<?> getListBoard(Board board,
			@PageableDefault(size = 10) 
			@SortDefault(sort = "reg_date", direction = Sort.Direction.DESC) Pageable pageable) {
		return ResponseEntity.ok(boardService.getListBoard(board, pageable));
	}
}

게시판 목록 조회시 @SortDefault 어노테이션을 이용하여 정렬 디폴트 옵션을 지정했다. 정렬기준 컬럼인 등록일자(reg_date) 컬럼 기준으로 내림차순(DESC) 정렬되도록 설정했다. 참고로 @SortDefault.SortDefaults 으로 정렬기준 컬럼을 여러개 설정할 수 있다.

BoardMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.company.helloBoard.domain.board.mapper.BoardMapper">

	<select id="getListBoard" parameterType="RequestList" resultType="Board">
		SELECT BOARD_ID , WRITER , TITLE , CONTENT , REG_DATE , UPDATE_DATE ,
		DELETE_DATE FROM BOARD <where>
			<if test="data.title != null and data.title != ''">
				AND TITLE LIKE '%' || #{data.title} || '%'
			</if>
			<if test="data.writer != null and data.writer != ''">
				AND WRITER LIKE '%' || #{data.writer} || '%'
			</if>
		</where>
		<!-- ✅ 동적 정렬 추가 -->
		<if test="pageable.sort.sorted">
			<trim prefix="order by">
				<foreach item="item" index="i" collection="pageable.sort" separator=",">
					${item.property} ${item.direction}
				</foreach>
			</trim>
		</if>
		OFFSET #{pageable.offset} ROWS FETCH NEXT #{pageable.pageSize} ROWS ONLY </select>
    
</mapper>

pageable이 제공하는 sort를 이용하여 property에는 정렬 대상컬럼 direction에는 오름차순/내림차순 정렬을 동적으로 처리하게끔 설정했다. 이 방식으로 Mybatis에서 Pageable 객체를 이용해 동적 정렬할 수 있다.

뷰에서 보여주기

image 폴더에 화살표 이미지 추가

sort arrow image.zip
0.00MB

 

style.css 파일 추가

.sort_desc {
	background-image: url(../image/sort_desc.png);
	background-repeat: no-repeat;
	background-position: right center;
	background-size: 20px auto;
	cursor: pointer;
}

.sort_asc {
	background-image: url(../image/sort_asc.png);
	background-repeat: no-repeat;
	background-position: right center;
	background-size: 20px auto;
	padding-right: 1.5rem;
	cursor: pointer;
}

list.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
	<meta charset="UTF-8">
	<title>게시판</title>
	
	<!-- ✅ 추가 -->
	<link type="text/css" href="/css/style.css" rel="stylesheet">
	<script type="text/javascript" src="/js/com-ajax.js"></script>
	<script type="text/javascript" src="/js/com-page.js"></script>
</head>
<script type="text/javascript">

	// 페이지 온로드시 게시글 목록 조회
	window.onload = function () {
		getList();
	}

	// 게시글 목록 조회
	function getList(pageNo) {
		pageNo = pageNo || 0;
		
		const title = document.querySelector("#title").value;
		const writer = document.querySelector("#writer").value;
		const sort = document.querySelector("#sort").value; // ✅ 파라미터 추가

		// ✅ 파라미터 전달시에도 추가
		const data = "?title=" + title + "&writer=" + writer + "&page=" + pageNo + "&sort=" + sort;
		
		AJAX.ajaxCall("GET", "/boards", data, afterGetList);
	}
	
	// 조회 후 처리
	function afterGetList(response) {
		
		// ✅ 페이징 처리
		PAGE.paging(response.totalPages, response.number, response.totalElements, "getList");
		
		// 결과 테이블 생성
		resultTable(response);
	}

	// 동적으로 테이블 생성
	function resultTable(response) {
		document.querySelector("#fieldListBody").innerHTML = "";
		
		if (response.size > 0) {
			const content = response.content;
			
			// ✅ 반복문 변경
			for (var i = 0; i < content.length; i++) {
				let element = document.querySelector("#fieldListBody");
				
				let result = content[i];
				let template = `
					<td><p>${PAGE.pageRowNumber(response.number, response.size, i, response.totalElements)}</p></td>
					<td><p>${result.title}</p></td>
					<td><p>${result.writer}</p></td>
					<td><p>${result.regDate}</p></td>
				`;
				element.insertAdjacentHTML('beforeend', template);
			}
		}
	}
	
	// 초기화
	function resetList() {
		document.querySelector("#title").value = "";
		document.querySelector("#writer").value = "";
		document.querySelector("#fieldListBody").innerHTML = "";
		
		// ✅ 화살표 초기화
		let reg_date = document.querySelector("#reg_date");
		if (reg_date.className == 'sort_asc') {
			reg_date.classList.toggle("sort_desc");
			reg_date.classList.toggle("sort_asc");
		}
		
		// ✅ 정렬 초기화
		document.querySelector("#sort").value = "";

		getList();
	}
	
	// ✅ 동적 정렬하는 부분 추가
	function dynamicSort(sortColumn) {
		let sortId = sortColumn.id;

		sortColumn.classList.toggle("sort_desc");
		sortColumn.classList.toggle("sort_asc");

		if (sortColumn.className == "sort_desc") {
			document.querySelector("#sort").value = sortId + ",DESC";
		} else {
			document.querySelector("#sort").value = sortId + ",ASC";
		}

		// 조회
		getList();
	}
	
</script>
<body>
	<div>
		<h2>게시판 목록</h2>
		<table>
			<tr>
				<th>제목</th>
				<td><input type="text" id="title"></td>
			</tr>
			<tr>
				<th>작성자</th>
				<td><input type="text" id="writer"></td>
			</tr>
			<tr>
				<td><button onclick="getList()">조회</button></td>
				<td><button onclick="resetList()">초기화</button></td>
			</tr>
		</table>
		<input type="hidden" name="page" id="page" value="0" />
		<!-- ✅ 정렬 요소 추가 -->
		<input type="hidden" name="sort" id="sort" value="" />
	</div>
	<div>
		<table>
			<colgroup>
				<col width="150px" />
				<col width="150px" />
				<col width="150px" />
				<col width="250px" />
			</colgroup>
			<thead>
				<tr>
					<th>No.</th>
					<th>제목</th>
					<th>작성자</th>
					<th>
						<!-- ✅ 정렬 대상 추가 -->
						<p class="sort_desc" id="reg_date" onclick="dynamicSort(this)">작성시간</p>
					</th>
				</tr>
			</thead>
			<tbody id="fieldListBody">
			</tbody>
		</table>
		<ul id = "pagingArea" class="pagination"></ul>
	</div>
</body>
</html>

화살표를 클릭할 때마다 sort 요소에 동적 정렬값이 세팅되서 조회되기 때문에, 아래와 같이 내림차순, 오름차순 정렬을 확인할 수 있다.

- 오름차순일 경우

- 내림차순일 경우