[JPA] Chapter 1. JPA란? - 1

joyful·2021년 6월 27일
0

JPA

목록 보기
1/18

들어가기 앞서

이 글은 김영한 님의 저서 「자바 ORM 표준 JPA 프로그래밍」을 학습한 내용을 정리한 글입니다. 모든 출처는 해당 저서에 있습니다.


1.1 SQL을 직접 다룰 때 발생하는 문제점

  • 관계형 데이터베이스는 가장 대중적이고 신뢰할 만한 안전한 데이터 저장소이며, 자바로 개발하는 애플리케이션의 대부분은 관계형 데이터베이스를 데이터 저장소로 사용함

    💡 관계형 데이터베이스(RDB, Relational Database)

    • 키(key)와 값(value)들의 간단한 관계를 테이블화 시킨 매우 간단한 원칙의 전산정보 데이터베이스
    • 데이터의 종속성을 관계(relationship)로 표현
  • 📊 JDBC API와 SQL

자바와 관계형 데이터베이스를 사용하여 회원 관리 기능(CRUD)을 개발하며 SQL을 직접 다룰 때의 문제점을 알아보자.


1.1.1 반복, 반복 그리고 반복

자바에서 사용할 회원(Member) 객체를 생성한다.

public class Member {
	
	private String memberId;
    	private String name;
        ...
}

회원 객체를 데이터베이스에 관리하기 위한 회원용 DAO(데이터 접근 객체)를 생성한다.

public class MemberDAO {
	
	public Member find(String memberId) {...}
}

회원 조회 기능을 위해 MemberDAOfind() 메소드를 작성한다. 개발 순서는 다음과 같다.

  1. 회원 조회용 SQL 작성
SELECT MEMBER_ID, NAME FROM MEMBER M WHERE MEMBER_ID = ?
  1. JDBC API 사용하여 SQL 실행
ResultSet rs = stmt.executeQuery(sql);
  1. 조회 결과를 Member 객체로 매핑
String memberId = rs.getString("MEMBER_ID");
String name = rs.getString("NAME");

Member member = new Member();
member.setMemberId(memberId);
member.setName(name);
...

회원 등록 기능도 만들어 준다.

public class MemberDAO {

	public Member find(String memberID) {...}
    	public void save(Member member) {...} // 추가
}

회원 등록 기능 개발 순서는 다음과 같다.

  1. 회원 등록용 SQL 작성
String sql = "INSERT INTO MEMBER (MEMBER_ID, NAME) VALUES (?, ?)";
  1. 회원 객체의 값을 조회하여 등록 SQL에 전달
pstmt.setString(1, member.getMemberId());
pstmt.setString(2, member.getName());
  1. JDBC API 사용하여 SQL 실행
pstmt.executeUpdate(sql);

회원 수정 및 삭제 기능도 위의 순서와 비슷하게 개발하게 될 것이다.

✅ 문제점

list.add(member); // 회원 객체를 자바 컬렉션에 보관시 한 줄로 저장 가능
  • 데이터베이스는 객체 구조와는 다른 데이터 중심의 구조를 가짐
    → 객체를 데이터베이스에 직접 저장·조회 x
    개발자가 객체 지향 애플리케이션과 데이터베이스 중간에서 SQL과 JDBC API 사용하여 직접 변환 작업 수행 필요

  • 객체를 데이터베이스에 CRUD하기 위한 SQL과 JDBC API를 엄청난 양의 코드로 작성해야 함
    → 테이블 마다 비슷한 업무 반복

1.1.2 SQL에 의존적인 개발

  1. 한 객체의 연관된 객체 사용 가능 여부를 전적으로 SQL이 권한 소유
    → SQL에 의존적인 개발을 피하기 어려움
    엔티티를 신뢰 및 사용 x

    엔티티(Entity) : 비즈니스 요구사항을 모델링한 객체

  2. DAO를 열어 실행되는 SQL의 종류와 조회되는 객체 일일이 확인 필요
    → 진정한 의미의 계층 분할이 어려움

1.1.3 JPA와 문제 해결

  • 데이터베이스에 객체 저장 및 관리시 JPA 제공 API 사용
    → JPA가 적절한 SQL 생성하여 데이터베이스에 전달
//저장
jpa.persist(member);

//조회
String memberId = "helloId";
Member member = jpa.find(Member.class, memberId);

//수정
Member member = jpa.find(Member.class, memberId);
member.setName("이름변경");

//연관된 객체 조회
Member member = jpa.find(Member.class, memberId);
Team team = member.getTeam();

1.2 패러다임의 불일치

객체와 관계형 데이터베이스가 지향하는 목적이 달라 기능과 표현 방법이 달라지는 것

1.2.1 상속

  • 비교

    항목지원 여부
    객체O
    테이블X
  • 문제점 : 상속 관련 패러다임 불일치 해결을 위해 소모하는 비용이 큼
    ex1) 객체 저장시 부모와 자식으로 분해하여 SQL 작성해야 함
    ex2) 객체 조회시 테이블을 조인하여 조회 후 객체 생성해야 함


1.2.2 연관관계

  • 연관관계 조회시 사용하는 기능

    항목기능조회 가능한 방향
    객체참조정방향
    테이블조인정방향, 역방향
  • 비교

    • 객체를 테이블에 맞추어 모델링

      • 객체를 테이블에 저장 및 조회시 편리
      • 객체가 참조를 통해 연관 객체 조회 불가
        • 관계형 데이터베이스는 조인을 통해 외래 키 자체 보관가능
        • 객체는 보관된 연관 객체의 참조를 통해 연관 객체 조회 가능
      • 객체지향 특징을 살린 좋은 객체 모델링을 기대하기 어려움
    • 객체지향 모델링

      • 참조를 통한 관계 형성

      • 연관관계 설정시 필요한 값

        항목외래키참조
        객체XO
        테이블OX

      → 개발자가 직접 연관관계 설정 해줘야 함


1.2.3 객체 그래프 탐색

한 객체에서 연관 객체를 조회할 때 참조를 사용하여 조회하는 방식

  • SQL을 직접 다루면 처음 실행하는 SQL에 의해 객체 그래프의 탐색 범위가 결정됨

  • 문제점

    • 객체 그래프의 탐색 방향을 코드만 보고 예측 불가능
    • DAO를 열어 SQL 직접 확인 필요 → SQL에 의존적인 개발
  • JPA의 연관 객체 조회 시점 설정

    항목외래키
    지연 로딩▪ 실제 객체를 사용하는 시점까지 데이터베이스 조회를 지연시키는 것
    ▪ 연관 객체 사용 시점에 적절한 SELECT SQL 실행
      → 연관 객체의 신뢰 및 사용 보장
    즉시 로딩엔티티 조회 시 연관관계에 있는 데이터까지 한 번에 조회해오는 기능

1.2.4 비교

  • row 구분

    항목구분 방법
    데이터베이스기본키 값
    객체▪ 동일성(identity) 비교
      : 객체 인스턴스의 주소 값 비교
    ▪ 동등성(equality) 비교
      : equals() 메소드를 사용하여 객체 내부 값 비교
  • 문제점 : 같은 데이터베이스 로우를 조회해도 객체는 다른 인스턴스로 인식
               → 동일성 비교 실패

String memberId = "100";
Member member1 = memberDAO.getMember(memberId);
Member member2 = memberDAO.getMember(memberId);

member1 == member2; //다름
  • JPA는 같은 트랜잭션일 때 같은 객체 조회 보장

1.2.5 정리

✅ 문제점

패러다임의 차이를 극복하기 위해 개발자가 중간에서 해결하는데 소비하는 비용(시간, 코드)이 너무 큼

✅ 해결방안

JPA를 통해 패러다임의 불일치 문제 해결 및 정교한 객체 모델링 유지가 가능함


1.3 JPA란 무엇인가?

  • JPA(Java Persistence API)

    • 자바 진영의 ORM 기술에 대한 API 표준 명세
    • 애플리케이션과 JDBC 사이에서 동작
    • 장점
      • 특정 구현 기술에 대한 의존도 감소
      • 다른 구현 기술로 손쉽게 이동 가능
  • ORM(Object-Relational Mapping)

    • 객체와 관계형 데이터베이스 매핑

    • 객체와 테이블 매핑 → 패러다임 불일치 문제 해결
      ∴ 객체지향 개발 가능

    • ORM vs SQL Mapper

      SQL MapperORM
      객체와 SQL 매핑객체와 관계형 데이터베이스 매핑
      반복적인 JDBC API 사용 및
      응답 결과 객체 매핑 작업 대신 처리
      반복적인 코드 및 SQL 작업 대신 처리
      개발자가 SQL을 직접 작성
      → SQL에 의존적인 개발
      SQL에 독립적인 개발

💡 JPA와 ORM의 차이

  • JPA는 표준 인터페이스이며, ORM은 JPA 구현체이다.
    => JPA는 ORM 프레임워크를 통해 사용 가능하다.

1.3.1 JPA 소개

  • 엔티티 빈(Entity Bean)

    • 엔터프라이즈 자바 빈즈(EJB)라는 기술 표준에 포함되어 있던 ORM 기술
    • 문제점
      • 복잡한 프로그래밍 모델
      • 낮은 기술 성숙도
      • 특정 구현 기술에 종속적
        ex) 자바 엔터프라이즈(J2EE) 애플리케이션 서버에서만 동작
  • 하이버네이트(Hibernate)

    • 자바 언어를 위한 객체 관계 매핑 프레임워크
    • EJB의 단점들로 인해 등장
    • 장점
      • 가벼움
      • 실용적임
      • 기술 성숙도가 높음
      • 특정 구현 기술에 대한 의존도 감소
        ex) 자바 엔터프라이즈 애플리케이션 서버 없이도 동작

1.3.2 왜 JPA를 사용해야 하는가?

  • 생산성 향상

    • 지루하고 반복적인 코드 및 SQL 작성을 대신 처리
  • 유지보수 용이

    • 엔티티 관련 SQL 및 JDBC API 코드 변경을 대신 처리
      → 유지보수 코드 수 감소
  • 패러다임의 불일치 해결

    • 객체지향 언어가 가진 장점들을 활용
      → 유연하고 유지보수하기 좋은 도메인 모델을 편리하게 설계 가능
  • 성능 향상

    • 다양한 성능 최적화 기회 제공
      • 같은 회원 여러번 조회시 SELECT SQL을 한 번만 전달하여 두 번째부터는 조회한 객체 재사용
      • Hibernate → SQL 힌트 넣을 수 있는 기능 제공
  • 데이터 접근 추상화와 벤더 독립성

    • 애플리케이션과 데이터베이스 사이에 추상화된 데이터 접근 계층 제공
      → 애플리케이션의 특정 데이터베이스 기술에 종속되지 않도록 함
  • 표준

    • JPA는 자바 진영의 ORM 기술 표준
    • 표준 사용 → 다른 구현 기술로 손쉽게 변경 가능



📖 참고

profile
기쁘게 코딩하고 싶은 백엔드 개발자

0개의 댓글