SQL 쿼리 매퍼 alias 불일치로 생기는 null 버그 정리
목차
SQL 쿼리 매퍼에서 alias가 제각각으로 붙어 있던 걸 한 번에 정리한 작업이다.
왜 alias가 이렇게 중요한가
MyBatis(iBatis) 기반의 sqlmap 쿼리 매퍼를 오래 운영하다 보면 어느 순간 같은 컬럼을 가리키는 alias가 파일마다 달리 붙어 있는 경우가 생긴다. 처음엔 개발자 개개인의 네이밍 습관 차이로 시작되는데, 시간이 지나면서 STATUS, status, statusCd, statusCode, STAT_CD 같은 이름들이 혼재하게 된다. Java 쪽 VO나 Map 으로 받아서 처리할 때, 키 이름 하나 다르면 값이 null로 내려오는 버그가 생기고, 그게 화면단에서 조건 분기를 타지 못하거나 잘못된 상태값을 표시하는 문제로 이어진다.
이번에 통일한 alias는 총 5개다.
| alias 항목 | 의미 |
|---|---|
status |
회원/대상의 상태 코드 |
gradeCode |
등급 코드 |
gradeLevel |
등급 레벨 |
statusName |
상태 명칭(한글 표시용) |
memberTypeName |
회원 유형 명칭 |
이 항목들이 여러 쿼리 파일에 흩어져 있으면서 alias가 조금씩 달랐던 거다. 팀원들이 각자 쿼리를 추가할 때 "어, 이 파일엔 이렇게 되어 있네" 하면서 따라 쓰는 게 아니라, 다른 파일 참고해서 작성하거나 기억에 의존해서 쓰다 보면 자연스럽게 벌어지는 일이다.
이런 불일치가 실제로 어떤 문제를 만드나
<!-- 어떤 쿼리 파일 A -->
<result column="MBR_STAT_CD" property="statusCode" />
<!-- 어떤 쿼리 파일 B -->
<result column="MBR_STAT_CD" property="status" />
<!-- 어떤 쿼리 파일 C -->
<result column="MBR_STAT_CD" property="statCd" />
Java 서비스 레이어에서 resultMap을 공통으로 쓰는 게 아니라 각 쿼리가 개별 매핑을 갖고 있으면, 같은 컬럼인데도 키 이름이 달라서 프론트엔드 혹은 JSP 템플릿에서 조건 처리가 일관성 없이 동작한다.
// status 로 받기로 했는데 어떤 쿼리는 statusCode 로 내려와서
String status = (String) map.get("status"); // null 이 되는 경우 발생
이 버그는 처음엔 특정 메뉴에서만 상태 표시가 빠진다거나, 등급명이 안 뜬다거나 하는 식으로 소소하게 나타난다. 근데 컴플라이언스 관련 쿼리에서 statusName, memberTypeName이 빠지면 관리자 화면에서 잘못된 판단을 유도할 수도 있어서 단순 UI 이슈로 가볍게 넘길 수가 없다. 이번 작업이 fix(compliance) 카테고리로 올라간 이유가 여기 있다.
팀 리딩 관점에서 이런 작업을 어떻게 다루는가
개인적으로 alias 통일 같은 작업은 기능 개발 PR에 섞이면 안 된다고 생각한다. 리뷰어가 변경 범위를 파악하기 어렵고, "이 쿼리에서 alias 바꾼 게 저 화면에 영향 주는 거야?" 하는 질문이 나오면서 리뷰 시간만 늘어난다. 그래서 이런 건 별도 커밋, 별도 PR로 분리해서 올리고, 커밋 메시지에 통일 대상 항목을 명시하는 게 맞다고 본다. 이번 커밋 메시지에 status/gradeCode/gradeLevel/statusName/memberTypeName 이렇게 항목을 쭉 나열한 것도 그 이유에서다. 코드리뷰 때 "어떤 alias를 어떤 이름으로 바꿨는지" 한 눈에 확인할 수 있도록.
팀원들한테도 이런 류의 수정은 왜 하는지 맥락을 짧게라도 공유하는 편이다. "이름 맞춘 거잖아요, 기능 변경도 아닌데" 라고 가볍게 볼 수 있지만, 서비스 레이어에서 alias 이름에 의존하는 분기 코드가 있으면 이게 곧 동작 변화로 이어진다. 그 연결고리를 이해해야 나중에 본인이 쿼리 추가할 때도 기존 alias 규칙을 맞춰서 쓰게 된다.
앞으로 이런 문제를 줄이려면
- 신규 쿼리 작성 시 공통 resultMap을 최대한 활용하고, 공통으로 뽑기 어려운 경우엔 alias 네이밍 컨벤션 문서를 참고하게 만드는 게 가장 현실적인 예방책
- 코드리뷰 체크리스트에 "alias가 기존 규칙과 일치하는가" 항목 하나 추가하는 것만으로도 이런 불일치가 쌓이는 속도가 꽤 줄어든다
- MyBatis를 쓴다면 resultMap을 분리된 파일(
resultMap.xml등)로 관리하고, 공통 컬럼 매핑은 그 파일 하나만 수정하면 전파되도록 구조를 잡는 것도 방법이다
쿼리 매퍼 alias 통일은 대단한 기능 개발처럼 보이지 않지만, 이게 안 되어 있으면 데이터가 제대로 내려왔는데도 화면에서는 없는 것처럼 보이는 디버깅하기 까다로운 버그들이 계속 올라온다. 조용히, 확실하게 해두는 게 맞다.
다음
댓글 0
첫 댓글 달아줘.