개발/JPA

[JPA] JPA란 무엇일까?

Jindory 2022. 2. 16. 07:29
반응형

안녕하세요. 개발자 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차 캐시와 동일성 보장
      String memberId = "100";
      Member member1 = jpa.find(Member.class, memberId);	//SQL 쿼리를 통한 조회
      Mebmer member2 = jpa.find(Member.class, memberId);	//1차 캐쉬에서 데이터 조회
      
      println(member1 == member2); // 같음(true)​
       같은 트랜잭션 안에서 동일한 객체 조회를 2번 조회했음에도 SQL은 첫번째 조회에만 실행하고 두번째 조회한 데이터는 1차 캐쉬에 있는 정보를 가져옴으로써 SQL을 1번 실행한다.
    • 트랜잭션을 지원하는 쓰기지연(Transactional write-behind)
      • INSERT
        /* 트랜잭션을 커밋할 때까지 INSERT SQL을 모아뒀다가 한번에 SQL을 전송 */
        transaction.begin();
        em.persist(memberA);
        em.persist(memberB);
        em.persist(memberC);
        // 여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
        
        // 커밋하는 순간 데이터베이스에 INSERT SQL을 모아서 보낸다.
        transaction.commit(); [트랜잭션] 커밋​
         데이터 저장(persist) 실행시 바로 SQL문을 DB로 전송하는것이 아니라 트랜잭션 commit과 동시에 SQL문을 DB로 전송함으로써 한번의 네트워크로 데이터 저장을 실행한다.
      • UPDATE
        /* UPDATE,DELETE로 인한 로우(ROW)락 시간 최소화*/
        trasaction.begin();
        changeMember(memberA);
        deleteMember(memberB);
        비즈니스_로직_수행();	// 비즈니스 로직 수행 동안 DB 로우 락이 걸리지 않는다.
        /* 트랜잭션 커밋 하는 순간 UPDATE, DELETE SQL을 실행 */
        transaction.commit();​
        UPDATE, DELETE로 인한 시간 최소화 및 트랜잭션 커밋과 동시에 UPDATE, DELETE SQL을 실행
    • 지연 로딩(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으로 인해 성능 저하가 발생할 수 있기 때문이다.
    •  
  • 데이터 접근 추상화와 벤더 독립성
  • 표준

  • 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

 

1.3 JPA란 무엇인가? · jpa

 

ultrakain.gitbooks.io

https://jgrammer.tistory.com/76

반응형