MyBatis를 사용하다 보면 Mapper XML에 직접 SQL을 작성할 일이 많아집니다.
그럴 때마다 selectUser
, getUserData
, query1
같은 제각각의 메서드 ID가 생겨나곤 하죠.
이런 네이밍은 시간이 지나면 협업과 유지보수에 혼란을 주기 딱 좋습니다.
그래서 이 글에서는 MyBatis Mapper XML의 SQL ID 명명 규칙을 통일하고
실무에서 사용하기 좋은 네이밍 패턴들을 정리해봤습니다.
왜 명명 규칙이 중요할까?
- 협업 중 “이 쿼리 뭐 하는 거야?”라는 질문을 줄일 수 있습니다.
- Git conflict나 Mapper ID 충돌을 방지합니다.
- SQL이 많아질수록 가독성과 검색 효율이 올라갑니다.
- 유지보수 시 수정할 쿼리를 빠르게 찾을 수 있습니다.
명명 규칙 기본 구조
동작 + 대상 + 조건
구성요소 | 설명 | 예시 |
동작 | SQL 유형 (select, insert, update, delete, count) | select |
대상 | 주 테이블 혹은 엔티티명 | User, Order |
조건 | 필터링 키 혹은 추가 설명 | ById, WithProfile, PageByKeyword |
자주 쓰는 명명 패턴 예시
<select id="selectUserById" ... />
- 사용 목적: PK 기반 단건 조회
- 파라미터:
userId
- 반환:
User
목록 조회
<select id="selectUserListByStatus" ... />
- 사용 목적: 특정 상태의 유저 목록
- 조건:
status
조인 조회
<select id="selectUserWithProfileById" ... />
- 사용 목적:
user + profile
조인 - 반환: DTO 객체
페이징 처리
<select id="selectPostPageByCategory" ... />
- 사용 목적: 카테고리 기준 페이지 단위 조회
- 파라미터:
category
, offset
, limit
삽입/수정/삭제
<insert id="insertUser" ... />
<update id="updateUserById" ... />
<delete id="deleteUserById" ... />
- 명확히 어떤 테이블, 어떤 조건으로 조작하는지 명시
피해야 할 명명 예
나쁜 예 | 문제점 |
getData, query1, customSelect | 의미 없음, 가독성 없음 |
selectAll | 조건 모호, 사용 범위 넓음 |
fetchSomething | 대상 불명확 |
실전 팁: 이름만 봐도 어떤 SQL인지 알 수 있게
- 이름만 보고도 "단건이냐, 목록이냐, 조인이냐" 가 보이도록 작성하세요.
- 필수 조건은
By
뒤에 명확하게. - 페이징 처리에는
Page
나 List
를 붙이는 걸 추천합니다.
명명 규칙 요약 정리
용도 | 명명 규칙 | 예시 |
단건 조회 | select{Entity}By{Field} | selectUserById |
목록 조회 | select{Entity}ListBy{Field} | selectUserListByRole |
조인 조회 | select{Entity}With{JoinEntity}By{Field} | selectOrderWithItemsByOrderId |
페이징 조회 | select{Entity}PageBy{Condition} | selectPostPageByKeyword |
삽입 | insert{Entity} | insertUser |
수정 | update{Entity}By{Field} | updateProductById |
삭제 | delete{Entity}By{Field} | deleteUserById |
카운트 | count{Entity}By{Condition} | countLoginByDate |
커스텀 Mapper 예시 (UserMapper.xml)
<mapper namespace="com.example.mapper.UserMapper">
<!-- 단건 조회 -->
<select id="selectUserById" resultType="User">
SELECT * FROM user WHERE id = #{id}
</select>
<!-- 목록 조회 -->
<select id="selectUserListByStatus" resultType="User">
SELECT * FROM user WHERE status = #{status}
</select>
<!-- 조인 -->
<select id="selectUserWithProfileById" resultType="UserProfileDto">
SELECT u.*, p.*
FROM user u
JOIN profile p ON u.id = p.user_id
WHERE u.id = #{id}
</select>
</mapper>
마무리
명명 규칙은 "팀의 약속"입니다.
MyBatis는 직접 SQL을 작성할 수 있는 만큼, 명명 방식만 통일해도 훨씬 안정적이고 유지보수하기 좋은 프로젝트가 됩니다.
필요하다면 이 명명 규칙을 [Notion이나 Confluence에 팀 룰로 등록]하고,
코드 리뷰에서도 규칙 위반을 바로잡는 문화를 만드는 걸 추천드립니다.
댓글