ORM 탄생 배경
DB 탄생 후 Java앱과 연동을 위해 JDBC 탄생
JDBC의 여러 문제로 QueryMapper 탄생
QueryMapper의 DB의존성 및 중복 쿼리 문제로 ORM 탄생
ORM은 갑자기 나타난 것이 아니라 점차 발전해온 DB 연동 기술 이론
=> jdbc < querymapper < orm 은 포함/개선 관계
JDBC의 여러 문제로 QueryMapper가 탄생
JDBC Template
- SQL Mapper 첫번째 주자로 JDBCTemplate 탄생
- 쿼리 수행 결과와 객채 필드 매핑
- RowMapper 로 응답필드 매핑코드 재사용
- Connection, Statement, ResultSet 반복적 처리 대신 해줌
- 😵💫 But, 결과값을 객체 인스턴스에 매핑하는데 여전히 많은 코드가 필요함
MyBatis
- SQL Mapper 두번째 주자로 MyBatis 탄생
- 반복적인 JDBC 프로그래밍을 단순화
- SQL 쿼리들을 XML 파일에 작성하여 코드와 SQL 을 분리!
- 😵💫 But, 결국 SQL을 직접 작성하는것은 피곤하다…(DB 기능에 종속적) 😫
- 😵💫 But, 테이블마다 비슷한 CRUD 반복, DB타입 및 테이블에 종속적이다.
QueryMapper 의 DB의존성 및 중복 쿼리 문제로 ORM 이 탄생했다.
- ORM 은 DB의 주도권을 뺏어왔다고 표현해도 과언이 아닙니다.
- ORM 은 DAO 또는 Mapper 를 통해서 조작하는것이 아니라 테이블을 아예 하나의 객체(Object)와 대응시켜 버립니다.
- 말이 쉽지…. 객체지향(Object) 을 관계형 데이터베이스(Relation) 에 매핑(Mapping) 한다는건 정말 많은 난관이 있습니다.
ORM의 성장과정
릴레이션(관계형 데이터베이스)를 객체(도메인 모델)로 매핑 하려는 이유?
- 객체 지향 프로그래밍의 장점을 활용할 수 있다.
- 이를 통해, 비즈니스 로직 구현 및 테스트 구현이 편리함
- 각종 디자인 패턴 사용하여 성능 개선 가능
- 코드 재사용
ORM 이 해결해야하는 문제점 과 해결책
상속의 문제
- 객체 : 객체간에 멤버변수나 상속관계를 맺을 수 있다.
- RDB : 테이블들은 상속관계가 없고 모두 독립적으로 존재한다.
💁♂️ 해결방법 : 매핑정보에 상속정보를 넣어준다. (`@OneToMany`, `@ManyToOne`)
관계 문제
- 객체 : 참조를 통해 관계를 가지며 방향을 가진다. (다대다 관계도 있음)
- RDB : 외래키(FK)를 설정하여 Join 으로 조회시에만 참조가 가능하다. (즉, 다대다는 매핑 테이블 필요)
💁♂️ 해결방법 : 매핑정보에 방향정보를 넣어준다. (`@JoinColumn`, `@MappedBy`)
탐색 문제
- 객체 : 참조를 통해 다른 객체로 순차적 탐색이 가능하며 콜렉션도 순회한다.
- RDB : 탐색시 참조하는 만큼 추가 쿼리나, Join 이 발생하여 비효율적이다.
💁♂️ 해결방법 : 매핑/조회 정보로 참조탐색 시점을 관리한다.(`@FetchType`, `fetchJoin()`)
밀도 문제
- 객체 : 멤버 객체크기가 매우 클 수 있다.
- RDB : 기본 데이터 타입만 존재한다.
💁♂️ 해결방법 : 크기가 큰 멤버 객체는 테이블을 분리하여 상속으로 처리한다. (`@embedded`)
식별성 문제
- 객체 : 객체의 hashCode 또는 정의한 equals() 메소드를 통해 식별
- RDB : PK 로만 식별
💁♂️ 해결방법 : PK 를 객체 Id로 설정하고 EntityManager는 해당 값으로 객체를 식별하여 관리 한다.(`@Id`,`@GeneratedValue` )