1. JPA의 필요성
대부분의 애플리케이션은 객체 지향 언어로 개발되고있다. 반면, 데이터베이스는 OracleDB, MySQL, SqlServer 등 관계형 데이터베이스(RDMBS)가 주류를 이루고 있다.
때문에, 객체화된 데이터를 관계형 데이터베이스에 저장하게 되는 상황이고 그것을 위해 개발자가 SQL문을 작성하게된다. 그러다보니 자연스럽게 애플리케이션 개발 자체가 SQL을 중심으로 진행이 되는데, 그 과정에서 아래와 같은 문제점이 발생한다.
- Entity마다 CRUD를 위한 쿼리 작성이 필요하다.
하나의 테이블 당 최소 4개의 SQL문(SELECT, INSERT, UPDATE, DELETE)을 작성해야한다! - 객체를 SQL로, SQL을 객체로 변환해주는 과정이 매번 필요하다.
- 테이블의 컬럼 구성이 변경되면 작성된 모든 쿼리의 수정이 필요하다.
(이건 최악이야) - 내가 자바 개발자인지 SQL짜는 기계인지 헷갈린다.
이런 문제점이 있지만, 그럼에도 관계형 데이터베이스는 주류에서 밀려나지 않을 것이다.
2. Object와 RDBMS의 차이
- 상속
- 객체에는 상속 관계가 존재한다.
- RDBMS에는 상속 관계가 존재하지 않는다.(대신, 슈퍼타입-서브타입 관계가 있다.) - 연관관계
- 객체는 참조를 통해 연관관계를 구현한다.
- 테이블은 외래키(FK)를 통해 연관관계를 구현한다. - 데이터 타입
- 데이터 식별 방법
3. JPA란?
Java Persistence API를 의미하며, Java 진영의 ORM 기술 표준이다. ORM은 Object-Relational Mapping(객체 관계 매핑)의 약자로, 객체와 DB의 데이터를 자동으로 매핑해주는 역할을 한다. 유념할것은 JPA는 ORM을 사용하기 위해 만든 인터페이스의 모음이라는 것이다.
JPA는 애플리케이션과 JDBC 사이에 존재한다. 애플리케이션에서 JPA의 메서드를 호출하면 JPA가 적당한 SQL을 생성해 JDBC API를 통해 DB서버에 질의를 하고 결과값을 받아와 다시 객체로 매핑해 반환시켜준다. 아래는 Member 객체를 DB MEMBER 테이블에 삽입하고 조회하는 순서도이다.
4. JPA로 바꾸면 뭐가 좋은데?
4-1. SQL 중심 개발에서 객체 중심 개발이 가능해진다.
4-2. 생산성을 증대시킬 수 있다.
JPA의 간단한 메서드를 사용해 SQL을 작성하지 않고 CRUD 구현이 가능해진다.
- 저장 : jpa.persist(member)
- 조회 : Member member = jpa.find(memberId);
- 수정 : member.setName("철수");
- 삭제 : jpa.remove(member);
4-3. 유지보수가 용이해진다.
- 기존 : 컬럼명 변경시 모든 SQL문을 수정해야함
- JPA : Member 클래스의 필드를 수정하면 끝
4-4. 패러다임의 불일치를 해결할 수 있다.
위와 같은 상황에서 ALBUM 테이블에 신규 데이터를 삽입한다면??
ALBUM 테이블의 데이터를 조회한다면??
- 기존
1Album album = jpa.find(Album.class, albumId);cs - JPA
12345SELECT I.*, A.*FROM ITEM IJOIN ALBUM AON I.ITEM_ID = A.ITEM_IDcs
5. JPA의 특징
- 객체 그래프 탐색 가능
12345678910class MemberService{...public void process(){Member member = memberDAO.find(memberId);member.getTeam(); //자유로운 객체 그래프 탐색member.getOrder().getDelivery();}}cs - 1차 캐시와 동일성 보장
123456String memberId = "100";Member m1 = jpa.find(Member.class, memberId); //SQLMember m2 = jpa.find(Member.class, memberId); //캐시println(m1 == m2) //truecs - 쓰기 지연
- 트랜잭션을 커밋할 때까지 INSERT SQL을 쌓아두고 한 번에 전송한다.
- UPDATE, DELETE로 인한 로우 락(Row Lock) 시간을 최소화한다.
123456789transaction.begin(); // [트랜잭션] 시작em.persist(memberA);em.persist(memberB);em.persist(memberC);//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.//커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다.transaction.commit(); // [트랜잭션] 커밋cs
12345678transaction.begin(); // [트랜잭션] 시작changeMember(memberA);deleteMember(memberB);비즈니스_로직_수행(); //비즈니스 로직 수행 동안 DB 로우 락이 걸리지 않는다.//커밋하는 순간 데이터베이스에 UPDATE, DELETE SQL을 보낸다.transaction.commit(); // [트랜잭션] 커밋cs - Lazy loading
- 객체가 실제 사용될 때 로딩(조회)된다.
12345Member member = memberDAO.find(memberId); // SELECT * FROM MEMEBER 수행Team team = member.getTeam();String teamName = team.getName(); // SELECT * FROM TEAM 수행cs
출처 :: 인프런 강의(자바 ORM 표준 JPA 프로그래밍 - 기본편)
'🌱 SPRING > JPA' 카테고리의 다른 글
[JPA] 플러시(flush) (0) | 2020.06.13 |
---|---|
[JPA] 영속성 컨텍스트 (0) | 2020.06.07 |
[JPA] JPQL 맛보기 (0) | 2020.06.07 |
[JPA] JPA로 CRUD 작성하기 (0) | 2020.06.06 |
[JPA] Dialect(방언) (0) | 2020.06.06 |