JPA - Java persistence API
JPA, 객체지향과 RDB 에 대한 고민을 했어. 이런 문제를 해결하기 위해서 JPA를 자바 진영의 ORM 표준기술로 제공하고 있어.
ORM은 뭐냐?
:Object-Relational Mapping(객체 관계db 매핑)
-객체는 객체대로 설계
-관계형 DB는 관계형 DB대로 설계
-ORM 프레임워크가 중간에서 매핑!
-대중적인 언어에는 대부분 ORM 기술이 존재하고 있다.
JPA는 애플리케이션과 JDBC 사이에서 동작한다
JPA는 어려운 개념이 아니다. 단순히 JAVA의 객체 -JDBC API - DB의 사이에서 매핑해주는 역할을 해준다.
예를 들어서 MemberDAO에 회원객체를 딱 넘기면(persist) JAP가 분석해서 INSERT 쿼리를 짬. 그리고 JDBC API를 통해서 DB로 넘겨줌.
단순히 쿼리 짜준다는 수준이 아니라, 패러다임의 불일치를 해결해준다.
// 1. 객체 분해
// 2.
INSERT INTO ITEM ..
// 3.
INSERT INTO ALBUM ..
이런 식으로 짰을 때? 쿼리가 복잡해졌지. 조회하는 것도 한 단계 더 복잡해졌고. 그래서 그냥 다들 super클래스를 사용했었고. JPA가 쿼리 다 짜줘. 복잡해진 그 단계를 JAP가 해주네?
+ 그러면서 패러다임 불일치를 해결할 수 있게 됐음! 조회할 때도(find) JPA가 알아서 앨범, 아이템 같이 join해서 값을 가져와서 앨범 객체를 반환해줌.
JPA 소개
java 표준으로 옛~날에 EJB 꾸지고, 코드 더러움.. 내가 만들어도 낫겠다. 하이버네이트 오픈소스로 직접 개발함. EJB 똥망 Java진영에서 반성함.. 미안ㅜ.ㅜ 표준화 하는 게 중요해. 표준 만들어서 팔아 먹어야징; 하이버네이트 만든 사람 데리고 와서 JPA 만듬. 거의 뭐 ctrl+c, ctrl+v 했음; 용의 정도 새로 정의
-JPA는 인터페이스의 모음 -JPA 2.1 표준 명세를 구현한 3가지 구현체가 존재 -하이버네이트, EclipseLink, DataNucleus..
우리는 그냥 하이버네이트 쓴다고 생각하면 됨!
이쯤 spring 프레임워크도 만들어지고, 표준화 되었음. 그래서 spring 프레임워크 + hibernate가 같이 많이 사용되었는데 우리나라는 mybatis가;; 국내는 1:9; 해외는 9:1. - (7-8년 전 자료)
JPA 를 왜 사용해야 하는가?
-SQL 중심적인 개발에서 객체 중심으로 개발 -생산성 -유지보수 -패러다임의 불일치 해결 -성능 -데이터 접근 추상화와 벤더 독립성 -표준
생산성 -JPA와 CRUD
저장 : jpa.persist(member) 조회 : Member member = jpa.find(memberId) 수정 : member.setName("변경할 이름"); 삭제 : jpa.remove(member);
수정이 좀 신기해. member.setName();하면 해줌... update 그런 거 없음. cache비스무리한 게 있어서
유지 보수 - 기존: 필드 변경 시 모든 SQL 수정
public class Member{
private String memberId;
private String name;
private String tel;
...
}
INSERT INTO MEMEBER(MEMBER_ID, NAME, TEL) VALUES
SELECT MEMEBER_ID, NAME, TEL FROM MEMBER M;
UPDATE MEMBER SET ... TEL = ?
tel 추가 됐다? 필요한 모든 쿼리에 tel을 추가해줘야 함... 안해도 됨
JPA와 연관관계, 객체 그래프 탐색
연관관계 저장
member.setTeam(team); //member에 team 세팅하고
jpa.persist(member); //넣으면 저장
객체 그래프 탐색
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();
//이것 두 개 따로 select해서 넣는 식으로 안해도 됨. 그냥 getTeam()할 수 있음.
나는 member를 가져왔는데 team이 조회가 되네? JPA가 member랑 관련 된 모든 테이블 가져와서 했나? 만약 50개 연관 되어있으면? 50개 테이블 가져올까??? 아니다. 우아한 방법으로 동작한다. getTeam()하고 사용하는 시점에 team 조회하는 테이블만 딱 가져온다. 조회 2번 해주는거지!
물론 한번에 join되어져서 table가져올 수 있게도 설정할 수 있다. LAGER로딩
신뢰할 수 있는 엔티티, 계층
class MemberService {
...
public void process(){
Member member = memberDAO.find(memberId);
member.getTeam(); // ㅇㅋ
member.getOrder().getDelivery(); //ㅇㅋ
}
}
이렇게 쭉쭉 연결해서 가져올 수 있음. 물론! 성능은 고민해야 함.
JPA와 비교하기
String memberId = "100";
Member member1 = jpa.find(Member.class, memberId);
Member member2 = jpa.find(Member.class, memberId);
member1 == member2; //같다고 나온다.
동일한 트랜잭션에서 조회한 엔티티는 같음을 보장. 마치 자바 collection에서 넣었다 뺐다 하는 것처럼 사용할 수 있다. 나머지 작업은 JPA가 해준다.
JPA와 성능 최적화 기능
그렇다면 쿼리 문 여러 번 보내는데... 성능이 느려지는 거 아닌가요?
-1차 캐시와 동일성( identity ) 보장
String memberId = "100";
Member member1 = jpa.find(Member.class, memberId); //SQL
Member member2 = jpa.find(Member.class, memberId); //캐시
member1 == member2; // true
같은 트랜잭션 내에서 member2에서 가져오는 거? 1차 캐시에서 가져옴. SQL 2번 나갈 꺼 1번만 나감 - 약간의 조회 성능 향상
-트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
1. 트랜잭션을 커밋할 떄까지 INSERT SQL을 모음
2. JDBC BATCH SQL기능을 사용해서 한번에 SQL 전송
transaction.begin(); //트랜잭션 시작
em.persist(memberA);
em.psesist(memberB);
em.persist(memberC);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다.
transaction.commit(); // 트랜잭션 커밋. 버퍼 기능을 해주는 거지!
-지연 로딩(Lazy Loading)
지연로딩 : 객체가 실제 사용될 때 로딩
즉시로딩 : JOIN SQL로 한번에 연관된 객체까지 미리 조회
//지연로딩
Member member = memberDAO.find(memberId); //SELECT * FROM MEMEBER
Team team = member.getTeam(); //이 팀 객체는 가짜 객체입니다. //**
String teamName = team.getName(); //SELECT * FROM TEAM
//즉시로딩
Member member = memberDAO.find(memberId); // SELECT M.*, T.* FROM MEMBER JOIN TEAM ...
Team team = member.getTeam();
String teamName = team.getName();
//** 최대한 미뤄서 실제로 쓸 때 가지고 옴. 그래서 지연 로딩이라고 함. // 객체 가져왔는데 사용 안 할 수도 있잖아! // 성능 안 나오네... 즉시 로딩으로도 할 수 있음. 얘네는 90% 같이 써! 그냥 같이 가져와→ 즉시 로딩
만약 현업에서 쿼리로 직접 짜? 개별로 쿼리 보내다가... 어 성능이 잘 안 나오네... 한방 쿼리로 바꿔봅시다! 아오 막막해;;; 쿼리 다 지우고 다시 짜야 해.. mapping해서 또 넣어야 하고;;
쿼리 하나 하나가 중요한 게 아니라 전체적으로 쿼리 성능이 어떤가 체크해야 함... 그래서 지연 로딩, 즉시 로딩 간편하게 바꿔서 돌려보고 필요한 지점에 필요한 테이블 형태를 결정할 수 있게 되는 거야.
→ ORM은 객체와 RDB 두 기둥 위에 있는 기술이다!
최적화.. DB.. 쿼리... 너무 중요해. 개발자는 쿼리 잘 짤 줄 알아야 해.. RDB, 객체 이해를 잘하고 있어야 해. JPA 쓰더라도 쿼리 잘 짤 수 있어야 해. 성능 최적화 거기 중요함
해당 포스팅은 T아카데미에서 진행한 김영한 강사님의 JPA 유튜브 강의를 듣고 정리한 것입니다 : ) https://www.youtube.com/watch?v=WfrSN9Z7MiA&list=PL9mhQYIlKEhfpMVndI23RwWTL9-VL-B7U
'Spring > JPA' 카테고리의 다른 글
JPA 필드와 칼럼 매핑 (0) | 2021.04.11 |
---|---|
JPA persistence.xml과 라이브러리 설정 (0) | 2021.04.11 |
JPA 기초와 매핑 : 실습 (0) | 2021.04.11 |
JPA 기초와 매핑 (0) | 2021.04.11 |
JPA, 객체지향과 RDB (0) | 2021.04.11 |
Uploaded by Notion2Tistory v1.1.0