JPA란 무엇인가?
먼저 JPA가 왜 등장하게 되었는지 그 환경부터 알아보자.
그렇다면 이때, 객체를 SQL로 변환하여 SQL을 작성하는 역할을 누가 하는가??
정답은 개발자이다. 개발자가 객체를 RDB에 저장할 수 있도록 SQL을 작성해주는 SQL Mapper 업무를 하였다.
즉 SQL 의존적 개발을 피할 수 없었다. 하지만 이는 유지보수가 너무 어려웠다.
예를들어 User라는 테이블이 있고 필드로 id, pwd 2개의 값만을 가진다고 생각해보자.
public class User {
private String userId;
private String password;
}
User 클래스를 코드로 위와 같이 나타낼 수 있다. 이를 조작하는 간단한 SQL을 작성하면 아래와 같다.
근대 만약 User 테이블에 TEL이 추가되어 아래와 같이 바뀌었다고 생각해보자
public class User {
private String userId;
private String password;
private Stirng tel;
}
그렇다면 기존 사용하던 SQL에 모두 TEL 항목이 추가되어야한다.
실무에서 사용되는 SQL은 훨씬 복잡하고 다양할 것이며 이를 모두 수정하는 것은 매우 어렵다.
동시에 객체와 RDB의 패러다임이 불일치에 따른 문제도 존재한다.
객체와 RDB 패러다임 불일치란 무엇일까??
크게 4개의 항목으로 알아볼 수 있다.
하지만 위와 같이 설계를 하더라도 문제가 있다.
상상만해도 머리가 아픈 작업이 필요함 -> DB 저장할 객체에는 상속 관계를 사용하지 않음
이를 테이블에 맞춰 모델링하면 아래와 같아진다.
class Member {
String id;
Long teamId; // TEAM_ID FK
String username;
}
class Team {
Long id; // TEAM_ID PK
String name;
}
테이블에 맞춰 객체를 설계할 경우 데이터베이스에 저장(INSERT)하는 것이 편리하다.
하지만 이것이 객체다운 모델링은 아니다. -> 객체는 참조로 연관관계를 맺는다.
객체에 맞춰 모델링하면 아래와 같다.
class Member {
String id;
Team team; // 참조로 연관관계를 맺음
String username;
Team getTeam() {
return team;
}
}
class Team {
Long id;
String name;
}
하지만 이 경우 데이터베이스에 저장(INSERT)하기가 어려워진다.
예시의 Member객체는 Team 객체를 참조하고 있을 뿐, Team의 PK를 직접적으로 가지고 있진 않다.
member.getTeam().getId()와 같이 가져올 수 있으나 번잡해진다.
심지어 조회를 할 경우에는 Member, Team을 Join을 통해 모두 가져온 후 각각의 Member, Team 객체에 세팅해 주어야 하기때문에 매우 복잡해진다.
SQL 중심적 개발은 처음 실행하는 SQL에 따라 탐색 범위가 결정된다.
-> 엔티티 신뢰 문제 발생 및 객체 그래프 탐색이 자유롭지 않음
객체 그래프 탐색?
객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다.
member.getTeam()과 같이 .을 통해 참조로 따라갈 수 있어야한다.
최종적으로 진정한 의미의 계층 분할이 어렵다.
String memberId = "10";
Member m1 = memberDAO.getMember(memberID);
Member m2 = memberDAO.getMember(memberID);
m1 == m2 // false! -> 각각의 새로운 객체를 생성하기 때문.
-> 결과적으로 객체답게 모델링 할 수록 매핑 작업만 늘어나게된다.
-> 같은 SQL을 통해 조회해 오더라도 서로 다른 객체에 저장하기 때문에 둘은 다른 객체이기 때문이다.
-> SQL을 작성하는 과정에 비용이 너무 들어가게 되기 때문에 이러한 설계를 결국 포기하게 됨
객체와 DB 사이의 데이터 타입간의 충돌이 존재한다.
Java 코드상에서 사용하는 데이터 타입을 DB에서 그래도 사용하기에 제약사항이 존재한다.
복잡한 변환과정 없이 간단한 코드로 위의 문제가 되었던 작업들을 처리 가능하다.
상속
// INSERT
list.add(album);
// SELECT
Album album = list.get(albumId);
Item item = list.get(albumId); // 다형성 활용
연관관계
list.add(member);
Member member = list.get(memberId);
Team team = member.getTeam();
}
비교
String memberId = "10";
Member m1 = list.get(memberId);
Member m2 = list.get(memberID);
m1 == m2 // true -> list가 같은 객체를 반환해줌
이와 같이 객체를 마치 java 컬렉션에 저장하듯 DB에 저장하는 방법을 계속 연구해온 결과 JPA가 등장하였다.