반응형
안녕하세요. 개발자 Jindory입니다.
오늘은 JPA에 대해서 알아보는 글을 작성해보고자 합니다.
JPA(Java Persistence API)란?
- Java에서 ORM 기술 표준으로, Java에서 제공하는 API이다.
- 기존 EJB에서 제공되던 엔티티 빈을 대체하는 기술이다.
- ORM 기술이기 떄문에 Java 클래스와 DB 테이블을 매핑한다.
- EJB(Enterprise Java Bean)
- 기업환경의 시스템을 구현하기 위한 서버측 컴포넌트 모델이다.
- 과거 ORM 기술이 접목되었던 기술로 업무 로직을 처리하는 역할을 했다.
- 허나 코드가 복잡하고, 인터페이스가 복잡하고, 속도가 느린 문제점이 존재
- Hibernate
- Java언어를 위한 ORM기반의 객체 관계 매핑 프레임워크이다.
- Gavin King과 시러스 테크놀로지스 출신 동료들이 EJB2 스타일의 엔티티 빈즈 이용을 대체할 목적으로 개발한 Open Source 프레임워크이다.
- JPA(Java Persistence API)
- Java 진영에서 EJB의 개선하기 위해 만든 ORM 기술이다.
- JPA는 인터페이스의 모음이며 Hibernate, EclipseLink, DataNucleus와 같은 구현체를 통해 구동된다.
- 버전
- JPA 1.0(JSR 220) [2006년] : 초기 버전. 복합키와 연관관계 기능이 부족
- JPA 2.0(JSR 317) [2009년] : 대부분의 ORM 기능이 포함, JPA Criteria가 추가
- JPA 2.1(JSR 338) [2013년] : 스토어드 프로시저 접근, 컨버터, 엔티티 그래프 기능 추가
ORM(Object-releational Mapping) 기술이란?
- Object-relational Mapping(객체 관계 매핑)으로 Java 의 객체를 관계형 DB와 매핑하기 위해 등장한 기술이다.
- Java의 Object를 SQL로 저장할때 ORM 프레임워크가 중간에서 매핑(SQL Query를 생성하여 데이터를)을 해준다.
JPA를 사용해야하는 이유
- SQL 중심적 개발에서 객체 중심개발
- 생산성 증대
- Java Collection에 값을 셋팅하는것과 같이 사용할 수 있다.
- 저장 : jpa.persist(member)
- 조회 : Member member= jpa.find(memberId)
- 수정 : member.setName("변경할 이름")
- 삭제 : jpa.remove(member)
- 유지보수
- 기존에 칼럼 칼럼추가시 해당 테이블과 관련된 모든 SQL를 수정해야 한다.
- JPA를 사용시 Entity에 필드만 추가만 해주면 SQL은 JPA가 수행한다.
- 패러다임 불일치 해결
- 상속
테이블이 위와 같이 Album,Movie,Book이 Item을 상속하는 관계에 있다고 가정했을때- 저장
개발자 :
jpa.persist(album);
JPA :
INSERT INTO ITEM...
INSERT INTO ALBUM... - 조회
개발자 :
Album album = jpa.find(Album.class,albumId);
JPA :
SELECT I.*, A.*
FROM ITEM I
JOIN ALBUM A ON I.ITEM_ID = A.ITEM_ID
- 저장
- 연관관계
- 객체의 참조로 연관관계를 저장이 가능하다.
- Member에 Team Entity가 포함되어 있는 경우 Member객체에 Team을 setting해주고 저장하면 Member와 Team을 연관지어 같이 저장한다.
Member member = new Member(); Team team = new Team();
member.setTeam(team);
jpa.persist(member);
- 객체 그래프 탐색
-
class MemeberService{ public void process(){ /*SQL을 구현한 DAO에서 가져온 Member객체에서 Team 조회*/ Member member1 = memberDAO.find(memberId); member.getTeam(); /*JPA를 통해 조회한 Memeber객체에 Team 조회*/ Member member2 = jpa.find(Member.class,memberId); member2.getTeam(); } }
- SQL로 구현한 결과로 가져온 Member에서는 SQL를 확인하기 전까지, Member에 Team을 포함한 정보를 가져왔는지 알 수 없기 때문에, member.getTeam()에서 Nullpoint Error가 발생 할 가능성이 있다.
- JPA를 사용시 객체간 연관관계를 파악하여, Team과 Member가 연관되어 있을경우
Eagar Loading(즉시 로딩)을 통해 Member와 Team정보를 조인하여 한번에 결과를 조회하여 Member에 연관된 Team정보를 조회 할 수 있다.
Lazy Loading(지연 로딩)을 통해 Member 정보를 조회한 후 Member에서 Team정보를 가져올때 Member와 연관된 Team정보를 조회함으로써, Member와 연관된 Team 정보를 조회 할 수 있다.
-
- 비교
String memberId = "100"; Member member1 = jpa.find(Member.class, memberId); Mebmer member2 = jpa.find(Member.class, memberId); member1 == member2; // 같음
- 동일한 트랜잭션에서 조회한 엔티티의 결과는 같음을 보장한다.
- 상속
- 성능
- 1차 캐시와 동일성 보장
같은 트랜잭션 안에서 동일한 객체 조회를 2번 조회했음에도 SQL은 첫번째 조회에만 실행하고 두번째 조회한 데이터는 1차 캐쉬에 있는 정보를 가져옴으로써 SQL을 1번 실행한다.String memberId = "100"; Member member1 = jpa.find(Member.class, memberId); //SQL 쿼리를 통한 조회 Mebmer member2 = jpa.find(Member.class, memberId); //1차 캐쉬에서 데이터 조회 println(member1 == member2); // 같음(true)
- 트랜잭션을 지원하는 쓰기지연(Transactional write-behind)
- INSERT
데이터 저장(persist) 실행시 바로 SQL문을 DB로 전송하는것이 아니라 트랜잭션 commit과 동시에 SQL문을 DB로 전송함으로써 한번의 네트워크로 데이터 저장을 실행한다./* 트랜잭션을 커밋할 때까지 INSERT SQL을 모아뒀다가 한번에 SQL을 전송 */ transaction.begin(); em.persist(memberA); em.persist(memberB); em.persist(memberC); // 여기까지 INSERT SQL을 데이터베이스에 보내지 않는다. // 커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다. transaction.commit(); [트랜잭션] 커밋
- UPDATE
UPDATE, DELETE로 인한 시간 최소화 및 트랜잭션 커밋과 동시에 UPDATE, DELETE SQL을 실행/* UPDATE,DELETE로 인한 로우(ROW)락 시간 최소화*/ trasaction.begin(); changeMember(memberA); deleteMember(memberB); 비즈니스_로직_수행(); // 비즈니스 로직 수행 동안 DB 로우 락이 걸리지 않는다. /* 트랜잭션 커밋 하는 순간 UPDATE, DELETE SQL을 실행 */ transaction.commit();
- INSERT
- 지연 로딩(Lazy Loading)
-
// 지연로딩 MEMBER member = meberDAO.find(memberId); SELECT * FROM MEMBER Team team = member.getTeam(); String teamName = team.getName(); SELECT * FROM TEAM // 즉시로딩 Member member = memberDAO.find(memberID); SELECT M.*. T.* Team team = member.getTeam(); FROM MEMBER String teamName = team.getName(); JOIN TEAM
- Lazy Loading(지연 로딩)은 객체가 실제 사용될때 해당 데이터를 DB에서 가져오는 방식으로 실제 사용될때 가져와서 지연 로딩이라고 한다.
- Eagar Loading(즉시 로딩)은 JOIN SQL을 통해 한번에 연관된 객체까지 미리 조회하여 데이터를 DB에서 가져오는 방식이다.
- 실제 업무에서는 Lazy Loading을 많이 사용하는데, 객체간 얼마나 연관되어 있는지 알 수 없기 때문에, Eagar Loading을 사용시 불필요한 SQL JOIN으로 인해 성능 저하가 발생할 수 있기 때문이다.
-
- 1차 캐시와 동일성 보장
- 데이터 접근 추상화와 벤더 독립성
- 표준
- JPA 동작 과정
- JPA는 Java 어플리케이션과 JDBC 사이에서 동작한다.
- 개발자가 JPA를 사용시, JPA 내부에서 JDBC API를 사용하여 SQL를 호출하여 DB에 SQL문을 전달하고 결과를 받아 Java 어플리케이션으로 전달해 준다.
JPA - 저장
Member객체 안의 데이터를 DB로 저장하는 과정은 아래와 같이 이루어진다.
- Member 객체의 정보를 persist를 통해 JPA로 넘긴다.
- Memeber Entity를 분석하여 INSERT SQL를 생성한다.
- SQL 쿼리를 생성하면서 패러다임 불일치(상속,연관관계,객체 그래프 탐색,비교)등 객체와 DB간의 다른점을 일치시켜준다.
(자세한 설명은 여기를 참조) - JDBC API를 사용하여 생성된 SQL를 DB에 전달한다.
JPA - 조회
Member객체 데이터를 DB에서 조회하는 과정은 아래와 같이 이루어진다.
- 조회하고자 하는 Member의 PK 정보를 JPA에 전달한다.
- 전달받은 엔티티 정보를 근거로 SELECT SQL를 생성한다.
- JDBC API를 사용하여 생성한 SELECT문을 DB로 전달한다.
- 반환된 결과값을 패러다임 불일치를 해결하여 Entity Object로 전달한다.
이렇게 JPA에 대해서 알아봤습니다.
혹시라도 정정할 내용이나 추가적으로 필요하신 정보가 있다면 댓글 남겨주시면 감사하겠습니다.
오늘도 Jindory 블로그에 방문해주셔서 감사합니다.
[참조]
SKplanet Tacademy - JPA 기본 다지기
https://www.youtube.com/watch?v=WfrSN9Z7MiA&list=PL9mhQYIlKEhfpMVndI23RwWTL9-VL-B7U
https://ultrakain.gitbooks.io/jpa/content/chapter1/chapter1.3.html
반응형
'개발 > JPA' 카테고리의 다른 글
[JPA] JPA 관련 application.properties 설정 (0) | 2022.04.27 |
---|---|
[JPA] 객체지향 쿼리 (0) | 2022.02.22 |
[JPA] JPA 영속성 컨텍스트 (0) | 2022.02.22 |
[JPA] JPA 연관관계 매핑 (0) | 2022.02.17 |
[JPA] JPA 기초 (0) | 2022.02.16 |