JPA 란
업데이트:
SQL을 직접 다룰 때 발생하는 문제점
비즈니스 요구사항을 모델링한 객체를 엔티티라고 하는데 SQL에 모든 것을 의존하는 상황에서는 개발자들이 엔티티르 신뢰하고 사용할 수 없다.
대신에 DAO를 열어 어떤 SQL이 실행되고 어떤 객체들이 함께 조회되는지 일일이 확인해야 한다.
이러한 방식은진정한 의미의 계층 분활이 아니다. 물리적으로 SQL과 JDBC API를 데이터 접근 계층에 숨겼어도 논리적으로 엔티티와 강한 의존관계로 조회하거나 필드를 추가할때 DAO의 CRUD 코드와 SQL 대부분을 변경해야 하는 문제가 발생한다.
요약
- 진정한 의미의 계층 분할이 어렵다.
- 엔티티를 신뢰할 수 없다.
- SQL에 의존적인 개발을 피하기 어려다.
패러다임의 불일치
상속
- 객체는 상속이라는 기능을 가지고 있지만 테이블은 상속이라는 기능이 없다.
- 데이터베이스 모델링에서 이야기하는 슈퍼타입 서브타입 관계를 사용하면 유사한 상태로 설계할 수 있다.
- 상속 된 객체를 저장할 때는 부모 객체와 자식 객체의 데이터를 각자 꺼내 INSERT를 작성해야 하고 타입도 지정해야 한다.
- 해당 객체들을 자바 컬렉션에 보관하면 부모 자식이나 타입에 대한 고민 없이 해당 컬렉션을 그냥 사용하면 된다.
JAP와 상속
JPA는 상속과 관련된 패러당미 불일치 문제를 개발자 대신 해결해준다. 개발자는 마치 자바 컬렉션에 객체를 저장하듯이 JPA에게 객체를 저하면 된다.
JPA를 사용해서 저장할때는 persist() 메소드를 사용해서 저장하면 된다. Item을 상속한 Album 객체를 저장하는 방법이다. JPA는 SQL을 실행해서 객체를 ITEM, ALBUM 두 테이블에 나누어 저장한다.
jpa.persist(album);
다음은 Alnum 객체를 조회하는 방법이다. find() 메소드를 사용해서 객체를 조회하면 된다. JPA는 ITEM과 ALBUM 두 테이블을 조인해서 필요한 데이터를 조회하고 그 결과를 반환한다.
String albumId = "id100"
Album album = jpa.find(Album.class, albumId);
연관관계
객체는 참조를 사용해서 다른 객체와 연관관계를 가지고 참조에 접근해서 연관된 객체를 조회 한다. 반면에 테이블은 외래 키를 사용해서 다른 테이블과 연관관계를 가지고 조인을 사용해서 연관된 테이블을 조회한다.
외래 키 컬럼을 사용해서 데이터 조회 가 가능하나 객체는 연관관계에서 한쪽으로 밖에 통신이 안되는 반면에 SQL은 양방향으로 조인이 가능하다.
SQL의 테이블의 컬럼을 그대로 가져와서 클래스를 만들면 테이블에 저장하거나 조회할 때는 편리하다. 그런데 외래키의 값을 그대로 보관하는 Id 필드에 문제가 발생하는데 SQL에서는 조인 기능이 있어 외래 키의 값을 그대로 저장하면 되는데 객체는 연관된 객체의 참조를 보관해야 연관된 객체를 찾을 수 있다. 이런 경우 개발자가 직접 Id값을 찾아 처리해야 하는 비용이 발생하게 된다.
JPA와 연관관계
JPA는 연관관계와 관련된 패러다임의 불일치 문제를 해결해준다.
member.setTeam(team); // 회원과 팀 연관관계 설정
jpa.persist(member); // 회원과 연관관계 함께 저장
개발자는 회원과 팀의 관계를 설정하고 회원 객체를저장하면 된다. JAP는 참조를 적절한 INSERT SQL을데이터베이스에 전달한다.
객체를 조회하는 경우에 외래 키를 참조로 변환하는 일도 JPA가 처리해준다.
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();
위의 예시는 어느정도 극복할 수 있는 문제들이다. 연관관계와 관련해서 극복하기 어려운 패러다임의 불일치 문제도 있다.
댓글남기기