학원에서 MyBatis로 1차 프로젝트를 했고 그 다음 수업 때 실습으로 JPA를 처음 써봤다.
2차에서는 둘을 같이 쓸 예정이라 정리를 할려고 한다.
둘 다 Java에서 DB에 접근하는 도구다. 목적은 같은데 방식이 다르다.
MyBatis는 SQL을 직접 작성한다. XML 파일에 쿼리를 적고 결과를 Java 객체로 받는 방식이다.
JPA는 SQL을 직접 안 써도 된다. 클래스에 @Entity를 붙이면 테이블이랑 매핑되고, 메소드 이름만으로 쿼리가 자동 생성된다.
<!-- MyBatis -->
<select id="findByUid" resultType="User">
SELECT * FROM user WHERE uid = #{uid}
</select>
// JPA
User findByUid(String uid);
같은 기능인데 코드 양 차이가 많이 난다고 생각했다.
장단점
MyBatis는 SQL을 직접 쓰니까 원하는 대로 쿼리를 짤 수 있다.
복잡한 JOIN이나 서브쿼리도 자유롭고, 쿼리가 눈에 보여서 디버깅하기 편하다.
대신 단순한 CRUD도 일일이 SQL을 써야 해서 코드가 많아진다.
JPA는 단순 CRUD는 거의 코드 없이 된다.
save(), findById() 같은 메소드가 기본 제공되고 메소드 이름만으로도 쿼리가 만들어진다.
대신 복잡한 조회는 어렵고, N+1 같은 문제가 생길 수 있다.
N+1 문제
JPA 쓸 때 자주 나오는 문제다. 목록 조회할 때 전체 목록 1번, 연관 데이터를 건마다 1번씩 추가 쿼리가 나가는 현상이다.
피드 10개 조회하면 피드 목록 1번 + 각 피드 좋아요 수 10번 = 11번 쿼리가 실행되는 식이다.
실습에서 이걸 MyBatis로 JOIN 쿼리 하나로 해결하는 걸 봤다.
MyBatis랑 JPA를 배웠으니, 둘 다 적용해보고 싶어서 프로젝트 2차도 이렇게 나눴다.
- 단순 CRUD → JPA
- 복잡한 쿼리, JOIN, 통계 → MyBatis
느낀 점
1차 때 MyBatis만 써봤을 때는 JPA가 뭔지 잘 몰랐다. 처음 배웠을 때는 솔직히 개꿀인데..? 라는 생각이 들었다.
직접 써보고 나서야 왜 편한지, 어디서 문제가 생기는지 이해됐다.
show-sql: true로 JPA가 실제로 날리는 쿼리를 확인하면서 보는 게 제일 도움됐다.