SQL을 직접 다룰 시에는 반복적인 동작을 계속 수행해야함..
JDBC API를 사용해서 SQL을 DB에 전달하는데, 새로운 객체가 생성 되거나 엔티티가 수정 될때마다 쿼리를 다시 작성하고 DB액세스 하는 작업을 계속 반복해야함..
DAO에는 항상 새로 추가되는 필드에 대한 메서드를 추가해야하고, 이를 하지않으면 올바른 서비스를 제공할 수 없게 된다.
엔티티를 사용할때마다 DAO를 일일이 확인하여 SQL이 원하는 방식으로 동작하는지 알아야 함을 뜻하는데, 이는 상당히 계층적이지 않고, SQL의존적이며, 비효율적이다. (코드 동작에 신뢰성이 없음)
도메인 모델을 객체로 모델링하여 사용하면, 객체지향의 장점을 가질 수 있지만 이를 저장할 때 문제가 발생한다.
예를 들어서 특정 객체가 다른 객체의 상속이나 참조를 하고 있다면 데이터를 저장할때 그와 연관된 데이터를 모두 함께 저장해야한다.
Abstract class Item{ Long id; String name; int price } class Album extends Item{ String artist; } class Movie extends Item{ String director; String actor; } class Book extends Item{ String author; string isbn; }
INSERT INTO ITEM... INSERT INTO ALBUM ...
객체에서는 연관관계를 참조하여 필드에 다른 객체를 넣지만 테이블에 저장할 때는 해당 방법이 어려우니, 외래키의 값으로 저장하는 경우를 가짐.
테이블은 참조가 필요없고 외래키만 있으면 되고, 개발자가 중간에 이를 변환하는 역할을 해 줘야함.
<클래스 엔티티>
class Member{
String id;
Team team;
String username;
Team getTeam(){
return team
}
class Team
Long id;
String name;
member.getId(); // MEMBER_ID PK 저장
member.getTeam().getId(); // TEAM_ID FK 저장
member.getUsername(); // USERNAME 칼럼에 저장
SELECT M.*, T.*
FROM MEMBER M
JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
public Member find(String memberId){
// sql 실행 ..
Member member = new Member();
// 데이터베이스에서 조회한 회원 관련 정보를 모두 입력 ..
Team team = new Team();
// 데이터 베이스에서 조회한 팀 관련 정보를 모두 입력 ..
// 회원과 팀 관계 설정
member.setTeam(team);
return member;
}
JPA는 위와 같은 참조를 알아서 외래 키로 반환해서 적절한 INSERT SQL을 데이터베이스에 전달한다.
조회시에도 적절한 외래키를 참조하여 반환해줌.