반응형
  • SQL 중심적인 개발의 문제점
  • JPA 소개

SQL 중심적인 개발의 문제점

-  무한 반복

- 지루한 코드

 

반복되는 CRUD 작업

INSERT INTO...

UPDATE...

SELECT...

DELETE...

자바 객체를 SQL로 ...

SQL을 자바 객체로 ...

 

public class Member {

   private String memberId;

   pirvate String name;

   ...

}

 

INSERT INTO MEMBER(MEMBER_ID, NAME) VALUES

SELECT MEMBER_ID, NAME FROM MEMBER M

UPDATE MEMBER SET ...

 

어느날 갑자기 요청사항으로 전화번호 칼럼 추가 요청이 오면 관련 테이블에 모두 수정 필요 

 

public class Member {

   private String memberId;

   pirvate String name;

   private String tel;  // 추가

   ...

}

 

INSERT INTO MEMBER(MEMBER_ID, NAME, TEL) VALUES // TEL 추가

SELECT MEMBER_ID, NAME, TEL FROM MEMBER M // TEL 추가

UPDATE MEMBER SET ... TEL = ? // TEL 추가

 

SQL에 의존적인 개발을 피하기 어렵다.

 

패러다임의 불일치! (객체 VS 관계형 데이터베이스)

객체와 관계형 데이터베이스의 차이

1. 상속

2. 연관관계

3. 데이터 타입

4. 데이터 식별 방법

 

1) 객체다운 모델링으로 개발

 

class Member {

   String id;

   Team team;  // 참조로 연관관계 맺는다.

   String username;



   Team getTeam() {

          return team;

   }

}



class Team {

   Long id;

   String name;

}

 

2) 객체 모델링 저장

member.getTeam().getId(); 를 이용해서 TEAM_ID에 넣는다.

 

INSERT INTO MEMBER(MEMBER_ID, TEAM_ID, USERNAME) VALUES ...

 

3) 객체 모델링 조회  

  객체다운 설계를 하여 조회를 하는데 오히려 복잡하고 맵핑 작업 시간이 더 걸려 결국엔 슈퍼 DTO 객체를 만들게 된다.

 

SELECT M.*, T.*

 FROM MEMBER M

  JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
public Member find(String memberId) {

   // SQL 실행 ... 

   Member member = new Member();

   // 데이터베이스에서 조회한 회원 관련 정보를 모두 입력

   Team team = new Team();

   // 데이터베이스에서 조회한 팀 관련 정보를 모두 입력



   // 회원과 팀 관계 설정

   member.setTeam(team);

   return member;

}

 

4) 처음 실행하는 SQL에 따라 탐색 범위 결정되는 경우

 

SELECT M.*, T.*

 FROM MEMEBER M

  JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID

 

member.getTeam(); // ok

member.getOrder(); // null 처음에 맴버과 팀만 가져왔기 때문에..  마음대로 사용자가 주문한 order 호출할 수가 없다..

 

만약에 memberDAO.find()를 다른 개발자가 개발했다면

엔티티 신뢰 문제 발생.. 개발자가 직접 눈으로 확인하지 않은 이상은 신뢰하고 사용하기 힘들다.

 

class MemberService {

  ...

 public void provess() {

    Mmber member = memberDAO.find(memberId);

    member.getTeam();  // ???

    member.getOrder().getDelivery();  // ???

}

 

모든 객체를 미리 로딩할 수는 없다.

상황에 따라 동일한 회원 조회 메서드를 여러개 생성한다.

 

memberDAO.getMember(); // Member만 조회

memberDAO.getMemberWithTeam(); // Member와 Team 조회

// Memberm, Order, Delivery

memberDAO.getMemberWithOrderWithDelivery();

 

그래서 자바 컬렉션에 저장하듯이 DB에 저장할 수는 없을까? 고민 끝에 JPA 등장!

JPA

- Java Persistence API

- 자바 진영의 ORM 기술 표준

 

ORM

- Object-relational mapping(객체 관계 매핑)

- 객체는 객체대로 설계

- 관계형 데이터베이스는 관계형 데이터베이스대로 설계

- ORM 프레임워크가 중간에서 매핑

- 대중적인 언어에는 대부분 ORM 기술이 존재

JPA는 애플리케이션과 JDBC 사이에서 동작

JPA 동작 - 저장

JPA 동작 - 조회

JPA는 표준 명세

- JPA는 인터페이스의 모음

- JPA 2.1 표준 명세를 구현한 3가지 구현체

- 하이버네이트, EclipseLink, DataNucleus

 

JPA를 사용하는 이유

- SQL 중심적인 개발에서 객체 중심으로 개발

- 생산성

- 유지보수

- 패러다임의 불일치 해결

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

- 표준

 

생산성 - JPA와 CRUD

저장 : jpa.persist(member)

조회 : Member member = jpa.find(memberId)

수정 : member.setName("변경할 이름")

삭제 : jpa.remove(member)

 

JPA의 성능 최적화 기능

1. 1차 캐시와 동일성(identity) 보장

2. 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)

3. 지연 로딩(Lazy Loading)

 

1차 캐시와 동일성 보장

1. 같은 트랜잭션 안에서는 같은 엔티티를 반환 - 약간의 조회 성능 향상

2. DB Isolation Level이 Read Commit이어도 애플리케이션에서 Repeatable Read 보장

 

String memberId = "100";

Member m1 = jpa.find(Member.class,  memberId); //SQL

Member m2 = jpa.find(Member.class,  memberId); //캐시

println(m1 == m2) // true

 

SQL문이 1번만 실행된다.

 

트랜잭션을 지원하는 쓰기 지연(transactional write-behind)

1. 트랜잭션을 커밋할 때까지 INSERT SQL을 모음

2. JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송

 

지연 로딩(Lazy Loading)

지연 로딩 : 객체가 실제 사용될 때 로딩

 

Member member = MemberDAO.find(memberId); => SELECT * FROM MEMBER

Team team = member.getTeam();

String teamName = team.getName(); => SELECT * FROM TEAM

 

즉시 로딩 : JOIN SQL로 한번에 연관된 객체까지 미리 조회

 

Member member = MemberDAO.find(memberId); => SELECT M.*, T.* FROM MEMBER JOIN TEAM ...

Team team = member.getTeam();

String teamName = team.getName();

 

 

 

** ORM은 객체와 RDB 두 기둥위에 있는 기술

** JPA 사용하기 전 과거로 돌아가고 싶지않다. (JPA 사용하는 어느 개발자가..)

    - 개발 인생에서 많은 시간을 SQL 생성하는데 투자하는데 그 시간을 아껴 더 좋은 코드를 생산할 수 있다.

 

 

참고 - 인프런 강의(자바 ORM 표준 JPA 프로그래밍 - 기본편, 김영한)

 

728x90
반응형

'JPA' 카테고리의 다른 글

JPA 순환 참조 원인 및 해결 방법  (0) 2021.08.26
JPA 연관관계 매핑 기초  (0) 2021.06.17
JPA 엔티티 매핑  (0) 2021.06.08
JPA 영속성 관리  (0) 2021.06.06

+ Recent posts