2024.11.21 - [Developer] - React 테이블 정렬 기능 구현하기 : 클라이언트 정렬부터 was서버까지 -1
이전 글에서는 React 클라이언트에서 정렬 상태를 관리하고, 이를 기반으로 데이터를 요청하는 방법을 다뤘습니다. 이번 글에서는 WAS와 SQL 쿼리를 수정하여 클라이언트에서 전달받은 정렬 조건(sortKey
, direction
)을 기반으로 데이터를 동적으로 반환하는 방법을 설명합니다.
📌 목표
- 클라이언트에서 전달받은 정렬 조건을 기반으로 SQL 쿼리를 동적으로 구성
- SQL Injection 방지 및 성능 최적화
- WAS Controller와 Service를 수정하여 데이터를 올바르게 반환
📂 기존 SQL 쿼리 분석
아래는 기존 제가 작성하던 SQL 쿼리입니다. 이 쿼리는 기본적으로 ROW_NUMBER()
를 사용하여 순번을 부여하고, 고정된 정렬 기준(ROW_NUM DESC
)을 사용합니다.
<select id="selectUserHistoryList" parameterType="java.util.HashMap" resultType="ParamMap">
SELECT
ROW_NUMBER() OVER(ORDER BY REG_DT ASC) AS ROW_NUM,
USERS_EMAIL,
USERS_LOGIN_DEVICE,
USERS_LOGIN_COURS,
DATE_FORMAT(REG_DT, '%Y-%m-%d %H:%i:%s') AS REG_DT
FROM USERS_ACCESS_HISTORY
WHERE 1=1
<if test="searchKeyWord != null and searchKeyWord != ''">
<choose>
<when test="searchKey == 'email'">
AND USERS_EMAIL LIKE CONCAT('%', #{searchKeyWord}, '%')
</when>
<otherwise></otherwise>
</choose>
</if>
<choose>
<when test="sortKey != null and sortDirection != null">
ORDER BY ${sortKey} ${direction}
</when>
<otherwise>
ORDER BY ROW_NUM DESC
</otherwise>
</choose>
LIMIT #{pageSize}
OFFSET #{startRow}
</select>
문제점:
- SQL Injection 위험:
${sortKey}
와${direction}
이 문자열로 직접 삽입되므로 악의적인 입력값에 취약합니다. - 기본값 설정 부족: 기본 정렬 기준이 명확하지 않다고 판단하였습니다.
🛠️ 수정된 SQL 쿼리
아래는 개선된 SQL 쿼리입니다. 동적 정렬 조건을 안전하게 처리하고, 불필요한 계산을 제거하여 성능을 최적화했습니다.
<select id="selectUsersHistoryList" parameterType="java.util.HashMap" resultType="ParamMap">
SELECT
ROW_NUMBER() OVER(ORDER BY REG_DT ASC) AS ROW_NUM,
USERS_EMAIL,
USERS_LOGIN_DEVICE,
USERS_LOGIN_COURS,
DATE_FORMAT(REG_DT, '%Y-%m-%d %H:%i:%s') AS REG_DT
FROM USERS_ACCESS_HISTORY
WHERE 1=1
<!-- 검색 조건 -->
<if test="searchKeyWord != null and searchKeyWord != ''">
<choose>
<when test="searchKey == 'email'">
AND USERS_EMAIL LIKE CONCAT('%', #{searchKeyWord}, '%')
</when>
<otherwise></otherwise>
</choose>
</if>
<!-- 동적 정렬 -->
ORDER BY
<choose>
<when test="sortKey != null and sortDirection != null">
<if test="sortKey == 'USERS_EMAIL' or sortKey == 'USERS_LOGIN_DEVICE' or sortKey == 'USERS_LOGIN_COURS' or sortKey == 'REG_DT'">
${sortKey} ${sortDirection}
</if>
</when>
<otherwise>
REG_DT DESC <!-- 기본값: 등록일 내림차순 -->
</otherwise>
</choose>
<!-- 페이징 처리 -->
LIMIT #{pageSize}
OFFSET #{startRow}
</select>
개선점:
- SQL Injection 방지: 허용된 컬럼만 정렬할 수 있도록 제한했습니다.
- 기본값 명확화: 기본 정렬 기준을 등록일 내림차순(
REG_DT DESC
)으로 설정했습니다.
📂 WAS Controller 및 Service 수정
Controller 코드:
@GetMapping("/users/access-history")
public ResponseEntity<List<Map<String, Object>>> getUsersHistory(
@RequestParam(required = false) String searchKey,
@RequestParam(required = false) String searchValue,
@RequestParam(required = false) String sortKey,
@RequestParam(required = false) String sortDirection,
@RequestParam int pageSize,
@RequestParam int startRow) {
Map<String, Object> params = new HashMap<>();
params.put("searchKey", searchKey);
params.put("searchValue", searchValue);
params.put("sortKey", sortKey);
params.put("sortDirection", sortDirection);
params.put("pageSize", pageSize);
params.put("startRow", startRow);
List<Map<String, Object>> historyList = userService.getUsersHistory(params);
return ResponseEntity.ok(historyList);
}
Service 코드:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<Map<String, Object>> getUsersHistory(Map<String, Object> params) {
return userMapper.selectUsersHistoryList(params);
}
}
📊 테스트 시나리오
1) 기본 요청 (등록일 내림차순):
GET /users/access-history?pageSize=10&startRow=0
2) 이메일 기준 오름차순 정렬:
GET /users/access-history?sortKey=USERS_EMAIL&sortDirection=ASC&pageSize=10&startRow=0
3) 검색 조건 + 접속기기 기준 내림차순:
GET /users/access-history?searchKey=email&searchValue=test@example.com&sortKey=USERS_LOGIN_DEVICE&sortDirection=DESC&pageSize=10&startRow=0
📌 결론 및 다음 단계
이번 글에서는 WAS와 SQL 쿼리를 수정하여 클라이언트에서 전달받은 동적 정렬 조건을 처리하는 방법을 되집어 보면서 설명하였습니다. 다음 추가로 진행할 내용은 지금까지 수정한 내용대로 했을경우 React 클라이언트측(화면)에서 정렬 데이터가 안넘어오는 오류가 발생하였는데 관련된 내용을 정리해볼까 합니다.
이전 클라이언트 측 정렬 진행 확인하기
2024.11.21 - [Developer] - React 테이블 정렬 기능 구현하기 : 클라이언트 정렬부터 was서버까지 -1
반응형
'Developer' 카테고리의 다른 글
React 테이블 정렬 기능 구현하기 : 클라이언트 정렬부터 was서버까지 -1 (0) | 2024.11.21 |
---|---|
[React]react-device-detect: 기기 감지 라이브러리 (0) | 2024.08.20 |
초보 개발자인 내가 사용하는 무료 소프트웨어 (0) | 2024.08.12 |
JSP 개념 이해하기 : 기초부터 차근차근 (0) | 2024.07.31 |
[React] App Router, Page Router 비교해보자 (0) | 2024.07.26 |