JPA (Java Persistence API)
- 개념: 자바의 ORM(Object-Relational Mapping) 표준 사양이다. 객체는 객체대로, DB는 DB대로 설계하고 그 사이를 JPA가 자동으로 매핑해 준다.
- 핵심: 개발자가 SQL을 직접 짜는 것이 아니라, 자바 컬렉션에 객체를 넣고 빼듯이 DB를 다루는 것이 목표이다.
MyBatis
- 개념: SQL Mapper 프레임워크입니다. 자바 객체와 SQL 문을 매핑해 주는 역할을 한다.
- 핵심: SQL 쿼리를 직접 작성하고, 그 결과를 자바 객체(DTO)에 담아주는 "쿼리 중심"의 기술이다.
장단점 요약
| 구분 | JPA | MyBatis |
| 장점 | - 높은 생산성: 기본적인 CRUD SQL을 자동 생성. - 유지보수 용이: 필드 변경 시 엔티티만 수정. - DB 독립성: DB 벤더가 바뀌어도 쿼리 수정이 거의 없음. - 객체지향 설계: 상속, 연관관계 등 객체지향적 모델링 가능. |
- SQL 세밀 제어: 복잡한 쿼리나 성능 최적화에 유리. - 낮은 러닝커브: SQL만 알면 빠르게 적응 가능. - 기존 시스템: 통계성 쿼리가 많거나 기존 SQL이 많은 프로젝트에 적합. |
| 단점 | - 높은 학습 난이도: 영속성 컨텍스트, 연관관계 등 개념이 복잡함. - 성능 최적화: 복잡한 쿼리 처리 시 추가 설정(QueryDSL 등) 필요. - 의도치 않은 쿼리: 잘못 설계하면 N+1 문제 등 성능 저하 발생. |
- 반복 작업: 단순 CRUD도 SQL을 일일이 다 써줘야 함. - DB 종속성: 특정 DB 전용 문법 사용 시 DB 교체가 어려움. - 객체-DB 분리: 데이터베이스 중심의 설계가 되기 쉬움. |
코드 예시 비교 (조회 기능)
JPA: 인터페이스만 정의하면 끝
// Entity 정의
@Entity
public class User {
@Id @GeneratedValue
private Long id;
private String name;
}
// Repository 정의
public interface UserRepository extends JpaRepository<User, Long> {
// 메서드 이름만으로 "SELECT * FROM User WHERE name = ?" 자동 생성
List<User> findByName(String name);
}
MyBatis: SQL을 직접 작성
<mapper namespace="com.example.mapper.UserMapper">
<select id="findByName" resultType="User">
SELECT id, name FROM users WHERE name = #{name}
</select>
</mapper>
// Mapper 인터페이스
@Mapper
public interface UserMapper {
List<User> findByName(String name);
}
차이점
1. 패러다임의 차이 (객체 vs SQL)
- JPA (Object-Relational Mapping):
- 관점: "DB 테이블을 자바 객체처럼 다루자."
- 개발자는 SQL을 고민하기보다 객체 간의 관계(연관관계)를 정의하는 데 집중한다.
- 데이터베이스의 로우(Row) 하나를 자바의 인스턴스 하나로 매핑하여 상태를 관리한다.
- MyBatis (SQL Mapper):
- 관점: "자바 메서드와 SQL 쿼리를 연결해 주자."
- 개발자가 직접 SQL을 작성하고, 그 실행 결과를 자바 객체(DTO/VO)에 채워주는 방식이다.
- 데이터베이스 중심의 사고방식을 그대로 유지하며 프로그래밍한다.
2. 데이터베이스 독립성
| 구분 | JPA | MyBatis |
| 유연성 | 매우 높음. 특정 DB에 종속되지 않음. | 낮음. 특정 DB 문법에 종속됨. |
| 원 | 각 DB(MySQL, Oracle 등)에 맞는 Dialect(방언) 설정을 통해 JPA가 적절한 쿼리를 자동 생성. | 개발자가 특정 DB의 전용 함수(예: Oracle의 DECODE, MySQL의 IF)를 사용하면 DB 변경 시 쿼리를 다 수정해야 함. |
3. 유지보수와 생산성
- JPA (높은 생산성):
- 필드 추가: 엔티티 객체에 변수 하나만 추가하면 관련 CRUD 쿼리에 자동으로 반영된다.
- 자동화: 테이블 생성(ddl-auto), 기본적인 CRUD 기능을 프레임워크가 대신 수행한다.
- MyBatis (명확하지만 번거로움):
- 필드 추가: 자바 객체 수정 + XML 파일 내의 모든 Insert, Update, Select 쿼리 및 ResultMap을 일일이 수정해야 한다.
- 명시적: 모든 쿼리가 눈에 보이기 때문에 흐름 파악은 직관적이지만 코드가 비대해진다.
4. 성능 최적화 방식
- JPA (최적화 기능 제공):
- 영속성 컨텍스트를 활용하여 1차 캐시, 쓰기 지연, 변경 감지 등으로 DB 접근 횟수를 줄인다.
- 하지만 복잡한 통계성 쿼리나 조인이 10개 이상 들어가는 대량 데이터 처리에는 QueryDSL 같은 추가 도구가 필수적이다.
- MyBatis (세밀한 제어 가능):
- 쿼리 자체를 개발자가 튜닝하기 때문에 최적화된 SQL을 직접 작성하기 유리한다.
- 데이터 용량이 매우 크거나, DB 프로시저를 많이 사용하는 환경에서 강점을 보인다.
5. 비교 요약표
| 비교 항목 | JPA | MyBatis |
| 학습 곡선 | 높음 (객체지향+DB 이해 필요) | 낮음 (SQL만 알면 쉬움) |
| 객체 모델링 | 중요 (연관관계 설정 중심) | 미미 (단순 데이터 전달 객체) |
| 성능 최적화 | 자동 최적화 + 튜닝 필요 | 수동 최적화 (개발자 역량) |
| 주사용처 | 신규 프로젝트, 비즈니스 로직 복잡 | 레거시 시스템, 통계 및 대량 배치 |
면접 답변식 요약
JPA는 생산성과 객체지향적 설계에 강점이 있고, MyBatis는 SQL에 대한 세밀한 제어에 강점이 있습니다.
현대적인 Spring 프로젝트에서는 JPA를 기본으로 사용하여 반복적인 CRUD 업무를 줄이고 도메인 로직에 집중하며, JPA로 구현하기 까다로운 복잡한 통계성 쿼리나 대량 처리가 필요한 부분에 대해서는 QueryDSL이나 MyBatis를 혼용하여 사용하는 것이 가장 효율적인 전략이라고 생각합니다.
'Daily Dev Q&A 정리 템플릿' 카테고리의 다른 글
| 26.01.14 DNS란? (0) | 2026.01.14 |
|---|---|
| 26.01.13 N+1 문제가 무엇이고 어떻게 해결하는가? (0) | 2026.01.13 |
| 26.01.08 JPA의 영속성 컨텍스트란? (0) | 2026.01.08 |
| 26.01.07 ORM이란? (0) | 2026.01.07 |
| 26.01.06 WAS와 웹서버란? (0) | 2026.01.06 |