4월 1주차 목표: JPA(ORM)에 기초 지식 다시 세우기
Member나 Team처럼 비즈니스 요구사항을 모델링한 객체를 Entity(엔티티)라고 한다.
객체는 참조를 통해서 관계를 맺는다. 하지만, 테이블은 기본 키(PK)와 외래 키(FK)를 이용해서 테이블의 관계를 맺는다. 이런 패러다임의 차이점을 가지고 있어서 개발자가 중간에 변환 역할을 해야한다.
하지만, JPA를 사용한다면 패러다임의 차이를 극복하기 위해서 불필요하게 작성하는 코드나 보일러 플레이팅 같은 코드를 생산하지 않아도 된다.
JPA를 사용하면 객체를 데이터베이스에 저장하고 관리할 때, 개발자가 직접 SQL을 작성하는 것이 아니라 JPA가 제공하는 API를 사용한다. 그러면 JPA가 개발자 대신에 적절한 SQL을 생성해서 데이터베이스에 전달한다.
jpa.persist(member)
Member m = jpa.find(Member.class, memberId);
Team t = m.getTeam();
member.setName("진호");
객체는 참조를 통해서 관계를 맺는다. 그런데, ORM을 사용하지 않은 상태에서 참조 객체를 탐색하기 위해서 참조하는 객체과 맵핑되는 테이블과 조인하는 쿼리를 작성해야 한다.
예를 들어, “select * from Member where id = $id” 쿼리의 결과로 생성된 Member객체는 Team 객체를 참조하면 null로 제대로된 탐색이 안된다. Member 객체와 연관 되어 있는 Team 객체를 참조 하고 싶다면 조인 쿼리를 새로 만들어야 하고 그렇게 되면 메서도 또한 새롭게 추가되어야 한다. 기능은 동일하나… 쿼리만 다른 형태로…
그런데, JPA를 사용하면 저렇게 비효율적으로 개발할 이유가 사라진다. 지연 실행(Lazy Execution) 방식으로 참조하는 객체를 사용할 때 JPA가 개발자를 대신해서 참조 객체와 맵핑되는 테이블과 조인 쿼리를 실행하고 그 결과를 참조 객체와 맵핑 시키기 때문에 객체 탐색 시, Null를 만나는 일은 사라진다.
패더라임의 불일치로 엔티티와 테이블과의 맵핑 시켜주는 일련의 보일러 플레이팅 코드를 작성해야하는 비효율적인 부분이 발생한다. 이로 인해, 우리는 주요 관심사에 집중하지 못하는 문제가 발생한다. 그리고 테이블에 대한 변경이 발생 했을 때, 단순히 엔티티만 변경하는 것이 아니라, 쿼리 부분까지 변경해야하는 부분이 발생하기 때문에 유지보수에도 문제가 발생한다.
그래서 우리는 ORM을 사용해야 한다.