4주차 자바 ORM 표준 JPA 프로그래밍 - 기본편

이재혁·2023년 6월 21일

강좌소개

강좌소개

SQL을 한땀한땀 작성하는 것은 개발 생산성이 떨어질 수 밖에 없다.

JPA⇒ 혁신

JPA 실무에서 어려운 이유!

  • 처음 JPA나 스프링 데이터 JPA를 만나면?
  • SQL 자동화, 수십줄의 코드가 한 두줄로!
  • 실무에 바로 도입하면?
  • 예제들은 보통 테이블이 한 두개로 단순함
  • 실무는 수십 개 이상의 복잡한 객체와 테이블 사용

목표 - 객체와 테이블 설계 매핑

  • 객체와 테이블을 제대로 설계하고 매핑하는 방법
  • 기본 키와 외래 키 매핑
  • 1:N, N:1, 1:1, N:M 매핑
  • 실무 노하우 + 성능까지 고려
  • 복잡한 시스템도 JPA로 설계 가능

목표 - JPA 내부 동작 방식 이해

  • JPA의 내부 동작 방식을 이해하지 못하고 사용
  • JPA 내부 동작 방식을 그림과 코드로 자세히 설명
  • JPA가 어떤 SQL을 만들어 내는지 이해
  • JPA가 언제 SQL을 실행하는지 이해

JPA 기본편 학습법

  • JPA는 표준 스펙만 500PAGE
  • 혼자서 공부하기는 쉽지 않음
  • 이론+라이브 코딩
  • 6단계의 실전 예제
  • 강의를 메인으로 하고, 책은 참고서로 추천
  • 총 16시간: 하루 1시간 반, 2주 완성

JPA 적용 사례

  • 우아한 형제들, 쿠팡, 카카오, 네이버 등등
  • 조 단위의 거래금액이 발생하는 다양한 서비스에서 사용, 검증
  • 최신 스프링 예제는 JPA 기본 적용
  • 자바 개발자에게 JPA는 기본 기술
  • 토비의 스프링 이일민님도 JPA는 기본 적용

JPA 저의 실무 경험담

  • 실무에서 수 많은 프로젝트를 JPA로 설계하고 개발
  • 저도 처음에는 좌충우돌, 고생
  • 동료들이 다시는 과거로 돌아가고 싶어하지 않음
  • 단순한 SQL 작성으로 내 인생을 낭비하지 않음
  • 남는 시간에 더 많은 설계 고민, 테스트 코드 작성
  • 개발이 정말 즐거워 짐

JPA 소개

SQL 중심적인 개발의 문제점

지금 시대는 객체를 관계형 DB에 관리

패러다임의 불일치

객체 vs 관계형 데이터베이스

상속

Album 조회

  • 각각의 테이블에 따른 조인 SQL 작성
  • 각각의 객체 생성
  • 상상만 해도 복잡
  • 더 이상의 설명은 생략
  • 그래서 DB에 저장할 객체에는 상속 관계 안쓴다.

연관 관계

  • 객체는 참조를 사용
  • 테이블은 외래 키를 사용

객체 모델링 조회

SELECT M.*, T.*
		FROM MEMBER M
		JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID
public Member find(String memberId) {
		//SQL 실행
		Member member = new Member();
		//데이터베이스에서 조회한 회원 관련 정보를 모두 입력
		Team team = new Team();
		//데이터베이스에서 조회한 팀 관련 정보를 모두 입력

		//회원과 팀 관계 설정
		member.setTeam(team);
		return member;
}

처음 실행하는 SQL에 따라 탐색 범위 결정

비교하기

  • member1, member2 데이터는 같지만 다른 인스턴스

비교하기 - 자바컬렉션

객체답게 모델링 할수록 매핑 작업만 늘어난다.

객체를 자바 컬렉션에 저장 하듯이 DB에 저장할 수는 없을까?

⇒JPA

JPA 소개

-Java Persistence API

-자바 진영의 ORM기술 표준

ORM?

  • Object-relational mapping(객체 관계 매핑)
  • 객체는 객체대로 설계
  • 관계형 데이터베이스는 관계형 데이터베이스대로 설계
  • ORM 프레임워크가 중간에서 매핑
  • 대중적인 언어에는 대부분 ORM 기술이 존재

JPA는 애플리케이션과 JDBC사이에서 동작

JPA 동작 - 저장

  • 객체를 저장할 때 객체를 MemberDAO에 넘기고
  • MemberDAO가 JPA에게 던지면 알아서 SQL을 만들어서
  • JDBC API를 활용해서 DB에 쿼리문을 날려준다
  • 패러다임의 불일치를 해결해준다

JPA 동작 - 조회

  • JPA에게 Id를 넘겨주면 select 쿼리를 만들어서 객체를 분석
  • JDBC API를 사용해서 ResultSet 매핑
  • 패러다임 불일치 해결
  • Entity Object를 만들어서 우리에게 반환해준다

JPA 표준 구현체로 Hibernate를 사용한다

JPA를 왜 사용해야 하는가?

  • SQL 중심적인 개발에서 객체 중심으로 개발
  • 생산성
  • 유지보수
  • 패러다임의 불일치 해결
  • 성능
  • 데이터 접근 추상화와 벤더 독립성
  • 표준

+패러다임 불일치란?
객체와 관계형 데이터베이스가 다르기 때문에 생기는 문제이다.
객체는 상속을 받지만 데이터베이스는 상속관계가 없다
이것을 해결하기 위해서 관계형 데이터베이스에서 조인을 사용하는 등
비용이 발생하는데 이런 과정이 모두 패러다임 불일치를 해결하는데
드는 비용이다.

생산성

  • 저장: jpa.persist(member)
  • 조회: jpa.find(memberId)
  • 수정: member.setName(”변경할 이름”)
  • 삭제: jpa.remove(member)

jpa가 관리하는 객체 ⇒ 엔티티

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

JPA와 비교하기

JPA의 성능 최적화 기능

  • 1차 캐시와 동일성 보장
  • 트랜잭션을 지원하는 쓰기 지연
  • 지연 로딩

1차 캐시와 동일성 보장

  • 같은 트랜잭션 안에서는 같은 엔티티를 반환 - 약간의 조회 성능 향상

SQL이 한번만 실행되고 그 다음에는 JPA가 들고 있는 메모리 상에서 반환을 해준다

⇒ SQL 한번만 실행

단, 같은 트랜잭션 안에서만 된다.

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

  • 트랜잭션을 커밋할 때까지 INSERT SQL을 모음
  • JDBC BATCH SQL 기능을 사용해서 한번에 SQL 전송

위 persist 3개를 모았다가 (커밋하기 전까지) 모아서 커밋한다.

⇒ 성능을 끌어올린다

Update는 생략.. 유료강의에서 설명

지연 로딩과 즉시 로딩

  • 지연 로딩: 객체가 실제 사용될 때 로딩
  • 즉시 로딩: JOIN SQL로 한번에 연관된 객체까지 미리 조회

JPA는 성능을 위해 지연 로딩과 즉시 로딩 두가지를 모두 지원한다

객체가 실제 사용될 때 로딩

Team 이 가끔 사용되는 경우

Member와 Team이 거의 같이 사용되는 경우

두 전략을 선택적으로 사용해서 성능 최적화를 고민해볼 수 있다.

JPA 시작하기

Hello JPA - 프로젝트 생성

study/h2/bin

h2.bat으로 실행(window)

H2 연결 에러 해결 참고

[H2] Database (디렉토리 경로) not found, either pre-create it or allow remote database creation

maven 프로젝트 생성(intellij)

hibernate.org

pom.xml 설정

<dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.3.10.Final</version>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.214</version>
        </dependency>
    </dependencies>

🔎EntityManagerFactory가 가지는 특징

1. 엔티티 매니저 팩토리는 하나의 데이터베이스에 하나만 생성한다. (생성 비용이 비싸기 때문)

2. 엔티티 매니저 팩토리는 여러 스레드가 동시에 접근해도 안전하다.

JPA 설정하기 - persistent.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             version="2.1">
    <persistence-unit name="hello">
        <properties>
            <!-- 필수 속성 -->
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
            <property name="javax.persistence.jdbc.user" value="sa"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

            <!-- 옵션 -->
            <!-- 콘솔에 하이버네이트가 실행하는 SQL문 출력 -->
            <property name="hibernate.show_sql" value="true"/>
            <!-- SQL 출력 시 보기 쉽게 정렬 -->
            <property name="hibernate.format_sql" value="true"/>
            <!-- 쿼리 출력 시 주석(comments)도 함께 출력 -->
            <property name="hibernate.use_sql_comments" value="true"/>
            <!-- JPA 표준에 맞춘 새로운 키 생성 전략 사용 -->
            <property name="hibernate.id.new_generator_mappings" value="true"/>
            <!-- 애플리케이션 실행 시점에 데이터베이스 테이블 자동 생성 -->
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            <!-- 이름 매핑 전략 설정 - 자바의 카멜 표기법을 테이블의 언더스코어 표기법으로 매핑
             ex) lastModifiedDate -> last_modified_date -->
            <property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
        </properties>
    </persistence-unit>
</persistence>

데이터베이스 방언

  • JPA는 특정 데이터베이스에 종속 x
  • 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다름
  • 방언: SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능

Hello JPA - 애플리케이션 개발

JPA 구동 방식

Persistence 가 persistence.xml을 읽어서 EntityManagerFactory에서 EntityManager를 찍어낸다

JPQL 소개(객체지향SQL)

  • 가장 단순한 조회방법
em.createQuery("select m from Member as m", Member.class).getResultList();

장점: 페이지네이션 시 limit을 설정할 수 있다.(setMaxResult(값))

  • 문제는 검색 쿼리

  • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 Entity 객체를 쿼리 할 수 있어야 한다

  • JPQL은 엔티티 객체를 대상으로 쿼리

  • SQL은 데이터베이스 테이블 자체를 쿼리

profile
서비스기업 가고 싶은 대학생

0개의 댓글