JAVA/JPA

(Spring Boot) JPA

ri5 2021. 6. 25. 17:28

JPA 란?


- java Persistebce API를 줄인 말로 자바 객체와 RDBMS(관계형 데이터베이스)간의 패러다임 불일치를

  해결하기 위한 자바 ORM

1) ORM

- Object-Relational-mapping (객체 관계 매핑)

- 관계형 데이터 베이스와 객체관의 매핑 정보로 ORM 프레임워크가 중간에서 매핑.

 

 

JPA 동작 원리


JPA 동작 원리

- JAVA 어플리케이션과 DB사이에 위치하여 매핑된 정보를 통해 만들어진 SQL문을 JDBC API를 통해 DB에 전달한다.

- 전달 받은 데이터는 Entity Object로 변환하여 사용한다.

 

 

JPA를 사용 하는 이유


1) SQL 중심 개발 -> 객체 중심 개발

- 객체간의 매핑된 객체를 기준으로 JPA에서 SQL문을 생성하기 때문에 객체 중심적으로 개발 가능.

데이터를 조회하는 과정

2) 생산성 증가

- 메서드를 통해 쉽게 데이터 처리를 할 수 있어 생산성 증가

   • 저장: jpa.persist(member)

   • 조회: Member member = jpa.find(memberId)

   • 수정: member.setName(“변경할 이름”)

   • 삭제: jpa.remove(member)

 

3) 유지보수가 쉬워짐

- JPA를 사용 하지않는다면 객체 요소 하나를 수정한다면

public class Member {
  private String memberId;
  private String name;
  // 객체를 수정함 number -> tel
  private String tel;
 }

- tel 과 관련된 SQL문들을 전부 수정해야함

INSERT INTO MEMBER(MEMBER_ID, NAME, TEL) VALUES
SELECT MEMBER_ID, NAME, TEL FROM MEMBER M
UPDATE MEMBER SET … TEL = ?

4) 패러다임 불일치 해결

- JPA와 상속

객체 상속관계로 테이블 Super Type과 서브 타입 관계로 구현 할 수 있다.

객체와 테이블 관계

- JPA 연관관계, 객체 그래프 탐색

연관 관계 저장

// member에 연관된 team 설정
member.setTeam(team);
// 데이터 저장
jpa.persist(member);

객체 그래프 탐색

Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();

 

자바 컬렉션에 데이터를 넣은 것처럼 넣었던 team데이터를 getTeam을 통해 손쉽게 사용할 수 있다.

 

- 신뢰할 수 있는 엔티티, 계층

class MemberService {
   ...
   public void process() {
   Member member = memberDAO.find(memberId);
   member.getTeam(); //자유로운 객체 그래프 탐색
   member.getOrder().getDelivery();
 }
}

JPA는 지연로딩을 통해 자유롭게 객체 그래프를 탐색할 수 있다.

4) 성능

- 1차 캐시와 동일성 보장

String memberId = "100";
Member m1 = jpa.find(Member.class, memberId); //SQL
Member m2 = jpa.find(Member.class, memberId); //캐시
println(m1 == m2) //true

같은 트랜잭션 안에서는 같은 엔티티를 반환.

 

- 트랜젝션을 지원하는 쓰기 지연

트랜잭션을 커밋할 때 까지 SQL문을 모음

- insert -

ransaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
//커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다.
transaction.commit(); // [트랜잭션] 커밋

- update -

transaction.begin(); // [트랜잭션] 시작
changeMember(memberA); 
deleteMember(memberB); 
비즈니스_로직_수행(); //비즈니스 로직 수행 동안 DB 로우 락이 걸리지 않는다. 
//커밋하는 순간 데이터베이스에 UPDATE, DELETE SQL을 보낸다.
transaction.commit(); // [트랜잭션] 커밋

 

- 지연 로딩과 즉시 로딩을 손쉽게 사용

• 지연 로딩: 객체가 실제 사용될 때 로딩

Member member = memberDAO.find(memberId); // SELECT * FROM MEMBER
Team team = member.getTeam();
String teamName = team.getName();  // SELECT * FROM TEAM

• 즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회

Member member = memberDAO.find(memberId);
Team team = member.getTeam();
String teamName = team.getName();  // SELECT M.*, T.* 
                                   //   FROM MEMBER
                                   //   JOIN TEAM …