일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- JPQL
- JPA
- 페이징
- jpa 활용
- 일론머스크
- 스프링 데이터 JPA
- 스프링 mvc
- QueryDSL
- 기본문법
- 컬렉션 조회 최적화
- 실무활용
- Spring Data JPA
- 불변 객체
- 로그인
- 검증 애노테이션
- 값 타입 컬렉션
- JPA 활용2
- JPA 활용 2
- 프로젝트 환경설정
- 벌크 연산
- 타임리프 문법
- 예제 도메인 모델
- 스프링
- 트위터
- 김영한
- 타임리프
- Bean Validation
- 스프링MVC
- API 개발 고급
- 임베디드 타입
- Today
- Total
RE-Heat 개발자 일지
[JPA] [1] JPA 소개 - SQL 중심적 개발의 문제점 본문
https://www.inflearn.com/course/ORM-JPA-Basic
인프런 김영한 님의 강의를 듣고 작성한 글입니다.
SQL 중심 개발의 문제점
객체 지향 언어 + 관계형 데이터베이스가 대세. 이런 식의 개발은 '객체'를 '관계형 DB'에 저장하는 양상을 띠고 있다.
다만 이런 방식은 SQL 의존적인 개발을 불가피하게 만든다.
예를 들어 객체에 tel이라는 필드가 추가되면 Member 클래스를 다루고 있는 모든 쿼리문을 수정해야 하는 번거로움이 발생한다.
객체와 관계형 데이터베이스의 차이
■ 상속
객체지향 언어의 상속뿐만 아니라 추상화, 다형성 개념이 관계형 데이터베이스엔 없다.
객체와 DB의 구성이 비슷해 보이나 실제 언어 작동에서 차이가 난다.
SQL
1] Album 저장
① 객체를 분해한다 → ② 분해 후 INSERT문 수행 (INSERT INTO ITEM...) → ③ ALBUM INSERT문도 수행
2] Album 조회
① 각각 테이블에 따른 조인 SQL을 작성 → ② 각각 객체 생성 등
자바
1] Album 저장
list.add(album);
2] 자바 컬렉션에서 조회하는 법
Album album = list.get(albumId);
부모 타입으로 조회 후 다형성도 활용가능
Item item = list.get(albumId);
■ 연관관계
객체 : 참조를 사용 member.getTeam()
관계형 데이터베이스 : 외래키를 사용한다. JOIN ON M.TEAM_ID = T.TEAM_ID
객체 연관관계에서 Member에서 Team을 참조할 수 있으나 Team에선 참조 불가하다. 반면 테이블에선 key를 이용해 서로를 참조할 수 있다.
객체를 테이블에 맞춰 모델링은 한다면?
Member 클래스에 teamId를 선언해 연관관계를 설정.
하지만 단순한 key값이 아니라 객체 참조값이 객체 지향 설계에 더 알맞다. 그에 맞게 객체를 설계하면 아래와 같이 설계할 수 있다.
참조로 연관관계를 맺는다면 TEAM_ID는 member.getTeam().getId()로 호출할 수 있다.
조회는 훨씬 복잡하다.
SQL에선 JOIN을 통해 Member와 Team을 조회한다. 하지만 이를 코드로 만들려면 Member 객체를 생성한 후 정보를 입력하고 Team도 생성 후 모든 정보를 입력하는 절차를 거쳐야 한다. 이후 회원과 팀의 관계를 설정한 뒤 member를 리턴해줘야 작업이 완료된다.
반면 위에서 봤듯이 자바 컬렉션에선
① list.add(member);로 저장하고
② Member와 Team 조회도
Member member = list.get(memberId)
Team team = member.getTeam();으로 간단히 수행할 수 있다.
■ 객체 그래프 탐색
객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다.
그러나 처음 실행하는 SQL에 따라 탐색 범위가 결정돼 버린다.
Member와 Team 그리고 Order가 연결됐지만, SQL은 Order에 대한 조회를 하지 않았으므로 nul이 뜬다.
이러면 엔티티 신뢰 문제가 발생한다. 직접 코드를 확인하기 전엔 어떤 값이 올지 확신하기 어렵다.
그렇다고 SQL문으로 연관된 모든 것을 조회하게 하려면 수많은 조인을 해야 하고, 이는 성능 저하를 불러일으킨다.
그래서 과거엔 조회 메서드를 여러 개 생성했다. 이런 방법으로 어떻게든 해결할 순 있지만, 복잡한 코드가 쓰여 진정한 의미의 계층 분할이 어렵게 된다.
■ 비교하기
같은 memberId로 조회해도 결괏값은 '다르다'가 나온다. 왜냐면 JDBC API를 통해 새로운 Memebr 인스턴스를 생성하기 때문이다.
String memberId = "100";
Member member1 = list.get(memberId);
Member member2 = list.get(memberId);
member1 == member2; //같다.
반면 자바 컬렉션에선 같은 값이 나오게 된다.
결과적으로 객체 지향적으로 모델링할수록 매핑작업이 어마어마하게 늘어난다.
그렇다면 객체를 자바 컬렉션에 저장하듯 DB에 저장할 순 없을까? 자바 진영에선 이러한 고민 끝에 JPA를 만들고 사용하게 된다.
'백엔드 > JPA' 카테고리의 다른 글
[JPA] [4] 엔티티 매핑(하편) - 기본키 매핑 (0) | 2023.08.06 |
---|---|
[JPA] [4] 엔티티 매핑(상편) (0) | 2023.08.05 |
[JPA] [3] 영속성 관리 - 내부 동작 방식 (0) | 2023.08.04 |
[JPA] [2] JPA 시작 - 프로젝트 생성 및 개발 (0) | 2023.08.04 |
[JPA] [1] JPA 소개 - JPA는 무엇인가? (0) | 2023.08.03 |