JPA란
Java Persistence API 직역은 자바 영속성 API 라는데... DB가 영속성이라서 그런건가.
JPA의 기본 컨셉은 자바 컬렉션
컬렉션에 add하거나 remove 하는 것 처럼.
자바 진영의 ORM 기술 표준임. 즉, 인터페이스
ORM은
Object Relational Mapping
객체 관계형데이터 맵핑
객체는 겍체대로 설계하고
DB는 DB대로 설계 하는데
ORM이 중간에서 매핑해 줌.
대부분 대중적인 언어는 ORM 기술이 존재함.
ORM은 RDB와 객체를 이어주는 기술임.
RDB도 잘 알아야 함.
ORM 에러의 많은 부분이 DB에서 일어날 거임.
결국 얘도 JDBC를 쓰는 거긴 함.
일종의 뭐 우리가 리스트 쓰듯이 (list.add()) 하듯이 하면 그걸 쿼리문으로 바꿔서 JDBC에 넣어주는 거지.
save의 경우
DAO는 리포지토리라고 보면 됨.
EntityObject는 Member같은.. 그런 오브젝트
persist는 저장한다는 거. 영속성 컨텍스트에 저장한다는 의미
여튼 persist 호출? 하면
넘겨준 객체를 분석하여 insert 쿼리를 만들고
jdbc를 통해 DB로 넘김
find의 경우
id를 넘기면
select 쿼리를 생성
resultSet에 대한 매핑도 다 알아서 해줌.
Jdbc를 통해 db에 넘김.
JPA의 구현체 몇개 있긴 한데,
그 중 하이버네이트를 가장 많이 씀.
JPA를 사용해야 하는 이유.
SQL 중심적인 개발에서 객체 중심으로 개발.
데이터 접근 추상화.
표준적임.
성능도 나쁘지 않음. 최적화 할수 있는 요지도 있음.
패러다임 불일치 해결
jpa.persist(member) 가 저장
member = jpa.find(memberId) 가 조회
member.setName("name") 가 수정
jpa.remove(member) 가 삭제
라고 하는 데..
수정 부분은 잘 모르겠네.
jpa로 한번 감싸진 member객체인가?
또 jpa는 sql 만들 필요가 없기에, 도메인에 필드만 추가하면 알아서 함.
jpa는 객체와 관계형 db의 패러다임 차이를 해결해 줌.
먼저 상속
저장
알아서 각각 테이블에 저장해 줌.
item이 album의 key를 가지고 있거나 그럴 듯.
조회
조회시엔 JOIN 해야 하는데,
타입, id 넘기면 알아서 Item과 Album 조인해서 가져 옴.
또, 연관관계? 그러니까 객체 안의 객체를 저장할 때도,
저렇게 setTeam() 해서 객체 넣어주면
알아서 외래키(team과 join으로 쓸 컬럼) 만들어서 insert 해 줌.
member에 team의 key로 쓸 값,
그리고 나머지 columns도 insert 되고,
또 team도 저 외래키를 가지고 team 테이블에 insert 될거임.
member에 teamId가 포함되어 저장되고,
또 team 자체도 team 테이블에 저장이 되는데, 여기서 team의 id는 member의 teamId가 됨.
member.getTeam()하면
member.getTeamId() 한 다음에 team 테이블에 select 쿼리 날릴 듯. 내부적으로.
그리고, JPA의 기본 컨셉은 컬렉션 이기 때문에
member1 = jpa.find(Member.class, id1);
member2 = jpa.find(Member.class, id1);
member1 == member2
같은 인스턴스로 판단됨.
마치 실제 컬렉션에서 똑같은 조건으로 두번 가져온 객체가 같다고 나오는 것 처럼.
항상 이런 건 아니고, 동일한 트랜잭션에 한해서임...
JPA는 JDBC와 JPA를 호출하는 무언가 사이에 위치.
보통 이렇게 무언가의 중간에 있는 것은
캐시와 버퍼링 write를 통해 성능 최적화 하는 것이 가능 함.
게다가 자동으로 해 줌.
조회시 같은 트랜잭션 안에서는 같은 거 호출하면 같은 엔티티(객체) 반환해주는 데 이것도 캐시한 거임.
트랜잭션 때 쓰기 지연
그러니까, sql들 모아서 한번에 전송하는 거임. 괜히 주고받고 주고받고 하면서 성능 낭비하지 말고.
commit 순간에 한번에 모두 보냄.
지연로딩
예를 들어, member가 객체를 가지고 있을 때, 그것이 DB상에서는 JOIN하여 가져오는 것이다.
근데 그것을 member를 가져올 때 미리 가져오는 게 아니라,
객체를 사용할 때 가져오는 것이다.
그러니까, member 그냥 그대로 가져왔다가,
team이라는 객체가 있으면 원래는 그냥 member가져와서 teamId만 member가 가지고 있었다가
getTeam()해서 쓸 때 team 테이블에서 가져오는 것이다.
member의 teamId를 통해서
왜냐하면 내가 team을 사용 안할수도 있으니까.
즉시 로딩은 그 반대.
봤더니 member쓰면 거의 무조건 team까지 같이 쓰는 상황.
default가 지연로딩이고, 무슨 설정을 줘서 즉시 로딩으로 바꿀 수 있음.
'스프링 > 6. 스프링 DB-2' 카테고리의 다른 글
27. JPA 예외 (0) | 2023.10.11 |
---|---|
26. JPA 적용 (0) | 2023.10.11 |
24. ORM (0) | 2023.10.10 |
23. JPA (0) | 2023.10.10 |
22. 마이바티스 기능들. (0) | 2023.10.10 |