JPA 사용하는 이유

홍윤기·2023년 1월 4일
0

개발일기

목록 보기
4/5

프로그램 구현에 앞서 Java의 세계에 들어온 이상 우린 객체 지향적으로 프로그래밍을 설계해야 합니다. 그렇다면 데이터는 어떻게 관리할까요?

Java - 객체 지향 언어, 현재 개발 언어의 트렌드
"DATA" - SQL기반의 관계형 DB/ Oracle, MySQL, PostgreSQL...

❌ SQL과 객체 지향의 충돌

1. 기능마다 CRUD SQL 실행

Java에서 아무리 객체 단위로 프로그램을 잘 설계해도 SQL기반의 관계형 DB를 사용하기 위해서는 CRUD 쿼리 개발이 중심이 될 수 밖에 없었습니다. 아래 예시와 같은 과정이 연속해서 수행되어져야 했죠.

@ INSERT, UPDATE, SELECT, DELETE 등의 쿼리를 객체마다 작성
@ 데이터가 담겨있는 자바 객체의 속성을, 쿼리 파라미터로 설정하는 로직 작성
@ 쿼리 결과를 다시 자바 객체로 변환하는 로직 작성

위처럼 반복되어지는 작업이 너무나도 많았고 무엇보다 프로그램이 실행이 되지 않다면 우리는 객체 지향 언어를 분석하는 것이 아닌 SQL 문을 분석하고 있어야 했습니다. 객체 지향 모델이 데이터 중심의 모델로 퇴화해버리는 것이죠.

2. 패러다임의 충돌

Java와 SQL은 시작지점부터 달랐습니다. 객체 지향 언어로써의 Java는 추상화, 캡슐화, 정보은닉, 상속, 다형성 등을 앞세워 시스템의 복잡성을 최대한 줄여 시스템 전반을 제어할 수 있는 다양한 기능을 제공할 수 있었죠. 하지만 관계형 데이터베이스로써 SQL은 데이터를 체계화, 정규화해서 저장하는 것이 목표였습니다.

객체 상속 관계에서는 상속 관계와 캐스팅이 자유로운 편이죠. 하지만 상속 받은 객체를 데이터 베이스에 저장하려면 어떻게 할까요?
위 entity diagram에서 Album, Movie, Book을 DB에 저장하기 위해서는 Album객체를 Item과 분리해서 Item Table에 하나, Album Table에서 하나씩 총 두개의 쿼리를 작성해서 저장합니다.

Movie 데이터를 조회할 때는 Item Table과 Movie Table을 조인하고 필드에 맞는 객체에 매핑시켜서 가져와야 합니다.

자, 방금 우리가 객체 지향을 사용했나요? DB에 저장하고 data를 검색하는 과정에서 상속 관계는 쓰이지 않았습니다.

문제는 이뿐만 아닙니다. 잘 알시다시피 객체는 참조를 사용하고 data는 FK(Foreign Key)를 사용하여 연관관계를 나타냅니다. 예시를 하나 더 들어보겠습니다.
객체의 참조는 Member.getTeam()을 통해 Member에서 Team으로 참조할 수 있습니다만 Team에서 Member는 참조할 객체가 없기 때문에 참조할 수 없습니다. 즉, 상호 참조가 안되죠.
테이블은 서로가 서로를 참조할 키(FK)가 있기 때문에 양측이 참조가 가능합니다.

Join Query를 나열하면서 해결하면 되지 않냐구요? 만약 Team -> Member -> Order -> OrderItem 처럼 객체 그래프 탐색을 진행해야 하는 상황을 가정해보면 Join Query를 직접 작성하고 있는 동안 IT에서 발을 빼자는 결심하게 될 것입니다.

3. 동일성(Identical)과 동등성(Equality)

String memberId = "100";
Member member1 = memberDAO.getMember(memberId);
Member member2 = memberDAO.getMember(memberId);

member1 == member2; // True? Or False?

놀랍게도 상황에 따라서 위 코드의 "member1 == member2"의 결과값은 True일수도, False일수도 있다.

class MemberDAO{
	public Member getMember(String memberId){
		String sql = "SELECT * FROM MEMBER WHERE MEMBER_ID = ?";
			...
		//JDBC API, SQL 실행
		return new Member(...);
	}
}

memberDAO 클래스를 다음과 같이 구성한다면 member를 조회할 때마다 new Member()를 통해 새로운 객체를 만들어서 조회하기 때문에 두 인스턴스 비교는 내용물이 같더라도 다릅니다. 객체는 동일성(==)과 동등성(equals)이라는 두가지 비교 개념이 존재합니다. 동일한 오브젝트라는 말은 같은 참조를 바라보고 있는 객체라는 말로 실제론 하나의 오브젝트라는 의미이고, 동등한 오브젝트라는 말은 같은 내용을 담고 있는 객체라는 의미입니다.

📢결론적으로

객체 지향으로 데이터를 모델링하는 것은 매핑 작업만 늘어나고 클래스끼리의 불일치가 늘어나서 사이드 이펙트가 커지기만 합니다.

0개의 댓글