[JPA] 자바 ORM 표준 JPA 프로그래밍 ch.1

박지운·2023년 4월 6일
0
post-thumbnail

김영한님의 '자바 ORM 표준 JPA 프로그래밍'을 읽고 정리한 글입니다.


1장 JPA 소개

1.1 SQL 직접 다룰 때 발생하는 문제

✔ 반복, 반복 그리고 반복

데이터 베이스는 데이터 중심의 구조를 가지기 때문에 객체 자체를 DB에 직접 저장, 조회 불가능
개발자가 객체지향 애플리케이션과 DB 중간에서 SQL과 JDBC API를 사용해서 변환 작업을 해야한다.

하지만 객체를 CRUD하려면 많은 SQL과 JDBC API를 코드로 작성, 테이블마다 비슷한 일을 계속 반복해야한다.


✔ SQL에 의존

SQL을 직접 다룰 때 문제점

1. 엔터티 신뢰 x

예시에서 Member객체가 연관된 Team 객체를 사용하는 것은 SQL에 달려있다.
-> 개발자들은 DAO를 열어서 일일히 확인해야 한다.
ex)

	Member member = memberDAO.find(memberId)
	member.getTeam(); 
	member.getName(); // 반환된 객체에 값이 들어있는지 없는지 모른다.

2. 진정한 계층 분할 X

수정 사항이나 버그가 생겼을 때 DAO를 열어 어떤 SQL이 실행되고 어떤 객체들이 조회되는지 확인해야한다.

3. SQL에 의존적인 개발을 피할 수 없다.

회원을 조회하거나 필드 하나 추가할 때도 매번 DAO의 CRUD와 SQL 대부분을 변경해야한다.


✔ JPA와 문제 해결

JPA를 사용하면 객체를 데이터베이스에 저장하고 관리할 때 직접 SQL을 작성하는 것이 아니라 JPA제공 API를 사용하면 된다


용어 정리

자바 컬렉션 : 인터페이스로 list, set, queue, map(분류상)을 포함한다.

DAO : Data Access Object
DB에 접근할 때 로직을 관리하는 객체
보통 관리 대상을 붙여 --Dao라 한다.
ex) User클래스 -> UserDao

엔티티 : 비즈니스 요구사항을 모델링한 객체, DB에서 테이블이라고 생각


1.2 패러다임 불일치

✔ 상속

객체는 상속이 있지만 테이블은 없다.
슈퍼 타입과 서브 타입으로 유사하게 설계할 수는 있다.

아래는 두 타입을 적용한 객체 모델 코드이다.

class Item {
	Long id;
    String name;
    int price;
}

class Album extends Item {
	String artist;
}

만약 ALBUM을 저장하려면 이 객체를 분해 해서 두 SQL문을 만들어야한다.

INSERT INTO ITEM ...
INSERT INTO ALBUM ...

그리고 JDBC API를 사용하려면 등록에서 ITEM은 부모 객체에서, Album은 자식 객체에서 꺼내 각각 INESRT SQL을 작성해야한다. 그리고 자식 타입에 따라 DTYPE도 저장해야한다. 벌써 번거롭다. 조회도 비슷한 맥락이다.


✔ 연관관계

객체는 참조, 테이블은 외래 키를 사용해서 조인을 통해 조회한다.

겍체를 테이블에 맞추어 모델링

class Member {
	string id;       //MEMBER_ID 컬럼
    Long teamId;		 //TEAM_ID FK 컬럼 사용
    String username; //USERNAME 컬럼 사용
}

class Team {
	Long id;
    String name;

위와 같이 객체를 모델링하면 Team 객체를 참조할 수 없다. 결국 객체지향을 쓰면서 객체지향의 특징을 잃어버린다.

JPA는 연관 관계와 관련된 패러다임 불일치도 해결해준다!!


✔ 객체 그래프 탐색

Team team = member.getTeam();

회원이 소속된 팀을 조회할 때 참조를 사용해 찾는다.
객체는 member.getOrder().getOrderItem().... 처럼 객체 그래프를 계속 탐색할 수 있어야하지만 SQL을 직접 다루면 처음 실행하는 SQL에 따라 탐색 범위가 한정된다.

JPA는 실제 객체 사용시점까지 DB조회를 미루는 지연 로딩을 통해 이 문제를 해결한다.

지연 로딩(LAZY) : 필요한 시점에 관련 객체를 불러오는 것(member 조회시  member만 조회하는 쿼리 생성)
즉시 로딩(EAGER) : 데이터 조회시 연관된 모든 객체를 불러오는 것(member 조회시 TEAM 조회 쿼리 까지 생성)

가급적 지연로딩 사용 권장❗

참고 : https://thalals.tistory.com/290


✔ 비교

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

위 코드에서 키 값이 100으로 같은 회원을 두 번 조회했다.
DB에서는 같지만 동일성 비교(==)를 하면 member1 == member2; false가 반환된다.
객체 측면에서 다른 인스턴스이기때문이다.

JPA에서는 같은 트랜잭션에서 같은 객체 조회되는 것을 보장한다.


✔ 정리

객체 모델과 관계형 데이터베이스 모델은 지향 패러다임이 다르다.
두 개념이 지향하는 목적이 달라 불일치가 발생하고 개발자는 이 차이를 극복위해 많은 시간과 코드를 소비해야한다.
--> JPA는 이를 해결해준다


1.3 JPA란

✔ JPA 소개

하이버네이트 기반 새로운 자바 ORM 기술 표준

JPA는 API 표준 명세서로 이를 구현한 ORM 프레임워크를 선택해야한다. 현재는 하이버네이트가 가장 대중적이다.


✔ 왜 JPA 사용?

1. 생산성

반복하고 반복적인 crud sql을 직접 작성하지 않는다.

2. 유지보수

엔티티에 필드를 추가하거나 삭제해도 수정 코드 양이 줄어든다.

3. 패러다임 불일치 해결

앞서 말한 상속,연관,탐색,비교의 불일치 문제 해결할 수 있다.

4. 성능

다양한 성능 최적화 기회를 제공한다.
SELECT문 2번 ➡ 1번 + 조회한 회원 객체 재사용

5. 데이터 접근 추상화와 벤더 독립성

추상화 접근 계층을 제공 어플리케이션이 특정 DB기술에 종속되지 않도록 한다.


1.4 정리

JPA를 쓰자

profile
앞길막막 전과생

2개의 댓글

comment-user-thumbnail
2023년 4월 7일

잘 봤습니다 진로가 생각나네요!!

1개의 답글