[JPA] JPA 프로그래밍 기본기 다지기 1강 - JPA 소개
업데이트:
💡JPA 실습 준비
- STS IDE 설치
- File -> New -> Spring Starter Project
- Type: Maven 선택 후 Next
- H2, JPA 선택 후 Finish
- H2 데이터베이스 설치
- h2폴더/bin/h2.sh (윈도우 h2.bat) 실행
- http://localhost:8082 접속
- 드라이버 클래스: org.h2.Driver
- JDBC URL: jdbc:h2:tcp://localhost/~/test
- 사용자명: sa, 비밀번호 생략 후 연결
💡1강 - JPA 소개
- 요즘 애플리케이션은 객체 지향 언어 ex)Java/Scala, Kotlin…
- 데이터베이스 세계의 헤게모니 관계형 DB(RDB) ex)Oracle, MySQL…
- 지금 시대는 객체를 RDB에 관리
✔문제점
1.SQL 중심적인 개발의 문제점
무한 반복, 지루한 코드
- CRUD를 계속해서 SQL작성한다.
- 객체에 필드가 추가된다면? 모든 쿼리문을 일일히 찾아서 수정해야함
- DAO에서 필요한 것들을 가져오는게 맞는지 확인해야 함
- 진정한 의미의 계층 분할이 어렵다.
- SQL에 의존적인 개발을 피하기 어렵다.
2.패러다임의 불일치
객체 VS 관계형 데이터베이스 => 나온 사상이 다름
- RDB: 철저하게 데이터를 어떻게 정규화할까에 포커싱
- 객체: OOP, 어떻게 추상화 해서 객체를 관리할까에 포커싱 → 이 두가지를 억지로 매핑해서 일을 처리해야함
- 객체 지향 프로그래밍(OOP)은 추상화, 캡슐화, 정보은닉, 상속, 다형성 등 시스템의 복잡성을 제어할 수 있는 다양한 장치들을 제공한다.
- 객체를 영구 보관하는 다양한 저장소: OBJECT -> RDB, NoSQL, File, OODB
- 객체를 RDB에 저장
- 객체 → SQL변환 → SQL → RDB
- 개발자가 SQL변환 과정을 한땀 한땀 해줘야함
- 개발자 === SQL매퍼
✔객체와 RDB의 차이
1.상속
- 객체는 상속관계가 있지만, 관계형 RDB는 상속관계를 사용하지 않는다.
2.연관관계★
-
객체는 참조를 사용: member.getTeam()
→ 객체 연관관계: 방향성이 있다. -
RDB 외래키를 사용: JOIN ON M.TEAM_ID = T.TEAM_ID
→ RDB 연관관계: 방향성이 없다. 하나가 있으면 왔다갔다 할 수 있다.
3.데이터타입
4.데이터 식별방법
✔객체를 자바 컬렉션에 저장하듯이 DB에 저장할 수 없을까?
→ JPA: Java Persistence API(영구 저장 API) 등장!
✔JPA?
Java Persistaence API, 자바 진영의 ORM 기술 표준
대표적인 오픈 소스가 Hibernate
- API껍데기만 있음, 인터페이스만 있다고 이해
- 이를 구현한 것이 Hibernate(하이버네이트)
- 애플리케이션과 JDBC사이에서 동작
- EJB 엔티티 빈(자바 표준) → 하이버네이트(오픈소스) → JPA(자바 표준)
- 해외는 JPA사용률 90퍼, MyBatis 사용률은 거의x (국내와 반대)
✔ORM?
Object-Relational Mapping(객체 관계 매핑)
객체와 DB의 테이블이 매핑을 이루는 것
- 객체는 객체대로 설계하고, RDB는 RDB대로 설계
- ORM프레임워크가 중간에서 매핑
- 대중적인 언어에는 대부분 ORM기술이 존재함
✔그렇다면, 왜 JPA를 사용해야 하는가?
- SQL중심적인 개발에서 객체 중심으로 개발
- 생산성, 유지보수, 성능
- 패러다임의 불일치를 해결★
- 데이터 접근 추상화와 벤더 독립성
생산성 - JPA와 CRUD
- 저장:
jpa.persist(member)
- 조회:
Member member = jpa.find(memberId)
- 수정:
member.setName("변경할 이름")
- 삭제:
jpa.remove(member)
유지보수
- 기존:필드 변경 시 모든 SQL수정해야함
- JPA: 필드만 추가하면 됨, JPA가 알아서 SQL처리
패러다임의 불일치
- 상속
- 개발자가 할일:
jpa.persist(album);
코드 작성 - 나머지 쿼리는 JPA가 처리:
insert into item..., insert into album...
- 개발자가 할일:
- 신뢰할 수 있는 엔티티, 계층
- 자유로운 객체 그래프 탐색
- JPA와 비교
- 동일한 트랜잭션에서 조회한 엔티티는 같음을 보장
JPA의 성능 최적화 기능
- 1차 캐시와 동일성(identity) 보장
- 트랜직션을 지원하는 쓰기 지연(transactional write-behinnd)
- 지연 로딩(Lazy loding)
- 동일한 트랜잭션에서 조회한 에티티는 같음을 보장
트랜잭션을 지원하는 쓰기 지연 - insert
- 트랜잭션을 커밋할때까지
INSERT SQL
을 모음 JDBC BATCH SQL
기능을 사용해서 한번에SQL
전송
transaction.begin(); //트랜잭션 시작
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//여기까지 INSERT SQL를 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL를 모아서 보낸다.
transaction.commit(); //트랜잭션 커밋
지연로딩과 즉시로딩
- 지연로딩: 객체가 실제 사용될 때 로딩
- 이때 필드에 있는 객체는 가짜(프록시) 객체임
- 즉시 로딩:
JOIN SQL
로 한번된 연관된 객체까지 미리 조회
✔결론
ORM은 객체와 RDB 두 기둥위에 있는 기술