1. 들어가며
BenePicker 프로젝트를 진행하면서 회원 기능과 조회 기능을 구현하다 보니 자연스럽게 이런 고민이 생겼다.
“MyBatis랑 JPA 뭐가 다른거지?”
“MyBatis는 XML 써야 되는 거 아닌가?”
“어노테이션이 더 편한데 왜 XML 쓰는거지?”
처음엔 단순히 “편한 거 쓰면 되는 거 아닌가?”라고 생각했는데, 직접 코드 작성하면서 생각이 완전히 바뀌었다.
2. MyBatis vs JPA — 근본적인 차이
처음엔 둘 다 그냥 “DB 연결 기술”이라고 생각했는데, 실제로는 패러다임 자체가 다르다는 걸 느꼈다.
→ MyBatis
- SQL을 직접 작성
- DB 중심 개발
SQL → 객체 매핑
→ JPA
- 객체(Entity) 중심
- SQL을 자동 생성
객체 → JPA가 SQL 생성
2. 핵심 깨달음
JPA는 “객체 중심”
MyBatis는 “SQL 중심”
이 차이를 이해하고 나니까 왜 두 기술이 공존하는지 이해가 됐다.
3. 프로젝트 구조 비교
1) MyBatis 구조
Controller
↓
Service
↓
Mapper + XML
↓
DB
2) JPA 구조
Controller
↓
Service
↓
Repository
↓
DB
(+ Entity 존재)
3) 중요한 차이 1 — Entity vs XML
처음에 내가 헷갈렸던 부분
“JPA는 Entity, MyBatis는 XML이 필요한 거 아닌가?”
✔️ JPA
- Entity 필수
- 없으면 사용 불가
✔️ MyBatis
- XML 선택
- 대신 SQL은 반드시 필요
4) MyBatis는 XML 없이도 된다
처음엔 XML이 필수인 줄 알았는데 어노테이션으로도 가능했다.
예시 (어노테이션 방식)
@Select("""
SELECT *
FROM member
WHERE member_email = #{memberEmail}
""")
Member findByEmail(String memberEmail);
→ 간단한 쿼리는 확실히 편하다
4. 그런데 왜 XML을 쓰는가?
프로젝트 진행하면서 직접 체감했다.
1) 동적 쿼리에서 차이 발생
검색 기능 구현할 때 문제가 터진다.
XML 방식
<select id="search">
SELECT *
FROM member
<where>
<if test="email != null">
AND member_email = #{email}
</if>
<if test="nickname != null">
AND member_nickname = #{nickname}
</if>
</where>
</select>
→ 조건이 늘어나도 깔끔하게 유지됨
어노테이션 방식
→ 거의 불가능 수준
- <if> 사용 불가
- 문자열 조합해야 함 → 가독성 박살
2) 쿼리가 길어질수록..
지도 + 검색 쿼리 작성하면서 느낀 점
- JOIN 여러 개
- 조건 많음
- GROUP BY / HAVING
→ 어노테이션으로 작성하면 복잡
3) 유지보수
XML은 SQL만 따로 관리 가능
- DB 튜닝 쉬움
- 쿼리만 수정 가능
- Java 코드 영향 최소화
선택 전략
이제는 기준이 명확해졌다.
간단 쿼리 → 어노테이션
복잡 쿼리 → XML
5. BenePicker 적용 기준
프로젝트 기준으로 나눠보면
JPA가 어울리는 영역
- 회원가입
- 로그인
- 프로필 수정
- 위시 리스트
→ CRUD 중심
→ MyBatis(XML)가 어울리는 영역
- 지도 기반 조회
- 검색 기능
- 필터링
- 추천 로직
→ 복잡한 SQL 중심
6. 최종 아키텍처 방향성 계획
Controller
Service
├── Repository (JPA)
├── Mapper (MyBatis)
→ 두 기술을 같이 사용하는 구조
7.결론
처음에는
“어노테이션이 더 편한데 왜 XML 써?”
라고 생각했지만, 지금은 생각이 바뀌었다.
“어노테이션은 작은 문제에서만 편하다”
“XML은 복잡한 문제를 해결하기 위한 도구다”
한 줄 회고
편한 기술보다 상황에 맞는 기술을 선택하는 게 더 중요하다
'백엔드 > 회고' 카테고리의 다른 글
| [Spring] JWT 로그아웃 기본 코드 분석 (0) | 2026.04.03 |
|---|---|
| [Swagger] Spring Boot Swagger 초기 설정 (feat. JWT 403 삽질기) (0) | 2026.03.31 |
| [GitHub] 협업 효율을 높여준 PR & Issue 템플릿 도입 (0) | 2026.03.31 |