2주차에 다루는 주제
<aside> 💡 교재 78p ~ 84p
</aside>
여러분, 1주차 레퍼런스에서 제가 스프링은 객체 지향 프로그래밍 사상을 위해 태어난 프레임워크를 말씀 드린 것 기억하시나요? JPA도 그와 같은 맥락으로 존재하는 기술입니다. JPA는 애플리케이션에서 데이터베이스를 다루는 기술이면서 코드를 객체 지향적으로 작성할 수 있도록 돕는 기술이에요. 데이터베이스를 다루는 기술이라 함은 서버 애플리케이션이 데이터베이스 서버에 SQL을 통해 데이터 보관과 관리를 요청하는 기술이라고 생각하시면 됩니다.
JPA를 사용하기 전에는 MyBatis와 같은 SQL Mapper를 사용했어요. MyBatis를 사용한 코드를 한번 볼까요?
(저는 예전에 자바 웹 개발을 배울 때 MyBatis로 프로젝트를 해봤는데요.. 정말 끔찍합니다 다시는 돌아가고 싶지 않아요)
코드를 보면 메소드 하나에서 DB Connection을 위한 빈 주입, 실행할 SQL 작성, SQL 실행, (여기엔 없지만 SQL 파라미터 매핑), SQL 실행 결과를 VO에 담는 과정을 모두 처리하고 있어요. 객체 지향 원칙의 SRP를 위반하고 있는게 우선 눈에 띄네요.
그리고 SQL을 직접 문자열로 타이핑한게 보이는데요. 이 SQL은 아주 간단하기 때문에 그리 어려워 보이지 않습니다. 하지만 실제로 개발을 해보면 저렇게 간단한 SQL만 사용하진 않아요. 여러 테이블을 조인하거나, 가져와야 하는 컬럼이 몇십개가 넘으면 아주 복잡한 SQL을 문자열로 작성해야 해요. 심지어 문자열로 쓰는거라 컴파일 시점에 SQL 오류를 잡아주지 못해요. 테이블이 수십, 수백개가 넘어가면 이러한 SQL을 무수히 많이 써야하고, 유지 보수가 어려워지며 결국은 끔찍한 코드로 변합니다.
가장 큰 문제는 SQL Mapper를 사용하면 스프링을 사용하다고 한들 코드를 객체 지향적으로 유지할 수 없다는 것입니다. 애플리케이션에서 SQL을 작성하는 비중이 커지다보니, 내가 작성한 자바 코드는 점점 SQL과 데이터베이스에 맞춰 변하게 돼요. 데이터베이스는 객체에 초점을 맞춘 스프링과 달리 데이터에 초점을 맞추고 있습니다. 클래스는 다른 객체를 필드로 포함할 수 있는 반면, 데이터베이스의 튜플은 해당 데이터베이스가 제공하는 기본 타입만 저장할 수 있는 것이 그 차이점이죠. 아무리 클래스를 아름답게 설계하더라도 데이터 전송 계층으로만 가면 객체로 잘 숨겨졌던 클래스가 기본 자료형 필드로 풀어져 버립니다. 이러면 객체 지향을 지켜 설계한 의미가 없어지겠죠?
이러한 문제들을 해결하기 위해 나온 것이 바로 JPA랍니다. JPA는 객체 지향과 데이터 지향이라는 서로 다른 패러다임 불일치를 해결해주는 어댑터 같은 존재입니다. JPA는 관계형 데이터베이스에 맞게 SQL을 대신 생성해서 실행해주기 때문에, 개발자는 객체 지향적인 코드를 표현하면서도 더 이상 SQL을 작성하는 것 때문에 스트레스 받지 않아도 됩니다.
우리가 사용할 Spring Data JPA는 Spring 진영에서 사용하는 JPA 기술입니다. 사실 JPA는 앞에서 설명한 패러다임 불일치를 해결해주는 기술의 인터페이스(명세서)이고, 이를 구현한 구현체들이 있어요. 대표적으로 Hibernate가 JPA 구현체 중 하나입니다. 개발자가 원한다면 Hibernate 외에 다른 구현체를 사용해도 됩니다. 그리고 이 Hibernate를 좀더 사용하기 편하게 추상화시킨 것이 바로 Spring Data JPA입니다. 교재에 나오는데 Spring Data Jpa는 저장소를 교체할 때 정말 편합니다. 개발 환경에서는 인메모리 DB인 h2를, 테스트나 실제 운영 환경에서는 Maria DB를 사용하고 싶으면 설정 파일에서 코드 몇줄로 바꿀 수 있어요. Spring Data JPA가 없었더라면 개발 환경을 하나 하나 세팅하고 있어야 할겁니다. 따봉 Spring Data JPA야 고마워!
JPA는 제가 개인적으로 좋아하는 주제라 이렇게 길게 설명을 해봤는데요, JPA 공부를 시작해보고 싶으신 분들께 다음과 같은 레퍼런스를 드립니다.