JPA와 MyBatis는 각각 명확한 장단점이 존재합니다.
JPA vs MyBatis 비교
| 구분 | JPA (OR Mapping) | MyBatis (SQL Mapper) |
| 패러다임 | 객체 중심 (DB 테이블을 자바 객체로 다룸) | SQL 중심 (자바 코드와 SQL을 분리하여 직접 제어) |
| 생산성 | 매우 높음 (반복적인 CRUD 및 SQL 작성 불필요) | 보통 (모든 쿼리와 매핑을 일일이 작성해야 함) |
| SQL 통제력 | 낮음 (JPA가 쿼리를 자동 생성) | 매우 높음 (원하는 대로 SQL 튜닝 및 제어 가능) |
| 학습 곡선 | 높음 (영속성 컨텍스트, N+1 문제, 연관관계 등 이해 필요) | 낮음 (기존 SQL 지식만 있으면 바로 사용 가능) |
1. JPA (Java Persistence API)
장점 👍
- 압도적인 생산성과 짧은 코드 양
- 단순 CRUD(저장, 조회, 수정, 삭제)용 SQL을 짤 필요가 전혀 없어 비즈니스 로직 작성에만 집중할 수 있습니다.
- 객체지향적인 코드 설계
- DB 테이블 중심이 아니라 자바 클래스의 상속, 연관관계(1:N, N:1 등), 객체 참조를 활용하여 도메인을 훨씬 깔끔하게 표현할 수 있습니다.
- 유지보수의 편의성 및 데이터베이스 유연성
- 테이블에 컬럼이 하나 추가되어도 XML 쿼리 수십 개를 수정할 필요 없이 Entity 클래스 필드만 수정하면 됩니다.
- DB를 MySQL에서 PostgreSQL이나 Oracle로 변경하더라도 JPA 설정(Dialect)만 바꿔주면 쿼리 재작성 없이 동작합니다.
- 캐싱 및 최적화 기능 (1차 캐시, Dirty Checking)
- 동일한 트랜잭션 내에서 중복 조회를 방지하고, 변경된 데이터만 추적하여 최적화된 UPDATE 쿼리를 전송합니다.
단점 👎
- 가파른 학습 곡선
- 단순히 사용법만 익혀서 쓰다 보면 N+1 문제, 영속성 컨텍스트 생명주기, 지연 로딩(LAZY) 관련 예외 등 의도치 않은 문제와 성능 저하를 겪기 쉽습니다.
- 복잡하고 통계 위주의 SQL 구현 한계
- 대규모 통계, 데이터 분석, 복잡한 서브쿼리와 조인이 수십 개 들어가는 쿼리는 JPA만으로 표현하기 까다롭습니다. (이를 보완하기 위해 Querydsl을 함께 사용합니다.)
- SQL 직관성 부족
- 내 자바 코드가 실제 DB에 어떤 SQL로 날아가는지 직관적으로 파악하기 어려워 프로파일링이나 SQL 튜닝이 비교적 어렵습니다.
2. MyBatis
장점 👍
- 원하는 대로 SQL을 직접 튜닝 및 최적화 가능
- 복잡한 조인, 통계 쿼리, DB 전용 함수(Stored Procedure 등)를 세밀하게 컨트롤할 수 있어 초고성능 튜닝이 필요한 시스템에 유리합니다.
- 낮은 진입 장벽
- 자바 기초와 SQL 문법만 알고 있다면 복잡한 ORM 개념을 공부할 필요 없이 즉시 개발이 가능합니다.
- 기존 legacy DB와의 연동 용이성
- 정교한 데이터 모델링 없이 복잡하게 뒤엉켜 있는 기존 RDB 구조 위에서도 자유롭게 SQL을 작성할 수 있습니다.
단점 👎
- 수많은 반복 작업 (보일러플레이트 코드)
- 간단한 조회/수정 하나를 만들려고 해도
Mapper 인터페이스 + XML + DTO세트를 매번 만들고 SQL을 직접 적어야 합니다.
- 간단한 조회/수정 하나를 만들려고 해도
- 유지보수의 번거로움
- DB 테이블 구조가 변경되면 해당 테이블과 연결된 모든 XML 파일의 SQL 및 결과 매핑(
resultMap)을 일일이 찾아 수정해야 합니다. (오타 발생 위험 증가)
- DB 테이블 구조가 변경되면 해당 테이블과 연결된 모든 XML 파일의 SQL 및 결과 매핑(
- DB 종속성 증가
- 특정 DB 전용 쿼리나 함수를 자주 쓰게 되므로, 추후 다른 데이터베이스로 전환하기가 매우 어렵습니다.
