66krap 2024. 2. 15. 20:51

JPA 시작

스프링과 JPA는 자바 엔터프라이즈(기업) 시장의 주력 기술이다.

스프링이 DI 컨테이너를 포함한 애플리케이션 전반의 다양한 기능을 제공한다면, JPA는 ORM 데이터 접근 기술을 제공한다.

 

스프링 + 데이터 접근기술의 조합을 구글 트렌드로 비교했을 때 

  • 글로벌에서는 스프링 + JPA 조합을 80%이상 사용한다.
  • 국내에서도 스프링 + JPA 조합을 50%정도 사용하고, 2015년 부터 추세가 점점 늘고있다.

JPA는 스프링 만큼이나 방대하고, 학습해야할 분량도 많다. 

하지만 한번 배워두면 데이터 접근 기술에서 매우 큰 생산성 향상을 얻을 수 있다.

대표적으로 JdbcTemplate이나 MyBatis 같은 SQL 매퍼 기술은 SQL을 개발자가 직접 작성해야 하지만, JPA를 사용하면 SQL도 JPA가 대신 작성하고 처리해준다.

 

실무에서는 JPA를 더욱 편리하게 사용하기 위해 스프링 데이터 JPA와 Querydsl이라는 기술을 함께 사용한다.

중요한 것은 JPA이고, 스프링 데이터 JPA, Querydsl은 JPA를 더 편리하게 사용하도록 도와주는 도구라고 생각하면 된다.

이 강의에서는 모든 내용을 다루지 않고, JPA와 스프링 데이터 JPA, 그리고 Querydsl로 이어지는 전체 그림을 볼 것이다.

그리고 이 기술들을 우리 애플리케이션에 적용하면서 자연스럽게 왜 사용해야 하는지, 그리고 어떤 장점이 있는지 이해할 수 있게 된다.

이렇게 전체 그림을 보고 나면 앞으로 어떻게 공부해야 할지 쉽게 접근할 수 있을 것이다.

 

JPA는 

build.gradle에

 //JPA, 스프링 데이터 JPA 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

추가하면 된다.

 

추가하면 다음과 같은 라이브러리들이 추가된다

  • hibername-core : JPA 구현체인 하이버네이트 라이브러리
  • jakarta.persistenc-api : JPA 인터페이스
  • spring-data-jpa : 스프링 데이터 JPA 라이브러리

application.properties에 다음 설정을 추가하자.

 #JPA log -- main
 logging.level.org.hibernate.SQL=DEBUG
 logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
 
 #JPA log -- test
 logging.level.org.hibernate.SQL=DEBUG

 

  • org.hibernate.SQL = DEBUG: 하이버네이트가 생성하고 실행하는 SQL을 확인할 수 있다.
  • org.hibernate.type.descriptor.sql.BasicBinder=Trace : SQL에 바인딩 되는 파라미터를 확인할 수 있다.
  • spring.jpa.show-sql=true: 참고로 이런 설정도 있고, 이전 설정은 logger를 통해서 SQL이 출력된다.
    이 설정은 System.out 콘솔을 통해서 SQL이 출력되서 권장되지 않는다.(둘다키면 System.out, logger 중복되서 출력된다.)

스프링 부트 3.0

3.0이상 부터는 하이버네이트 6버전을 사용해서 로그 설정 방식이 달라졌다. 

다음과 같이 설정하자.

 #JPA log
 logging.level.org.hibernate.SQL=DEBUG
 logging.level.org.hibernate.orm.jdbc.bind=TRACE

 

JPA 적용 1 - 개발

JPA에서 가장 중요한 부분은 객체와 테이블을 매핑하는 것이다. 

JPA가 제공하는 애노테이션을 사용해서 Item 객체와 테이블을 매핑해보자.

 

- @Entity : JPA가 사용하는 객체라는 뜻이고, 이 애노테이션이 있어야 JPA가 인식할 수 있다 

- @Id 테이블의 PK와 해당 필드를 매핑한다.

- @GenerateValue(strategy = GenerationType.IDENTITY) : PK 생성 값을 데이터베이스에서 생성하는 IDENTIFY 방식을 사용한다.

- @Column : 객체의 필드를 테이블의 컬럼과 매핑한다.

 

JPA의 모든 동작은 엔티티 매니저를 통해서 이루어진다.

엔티티 매니저는 내부에 데이터소스를 가지고 있고, 데이터베이스에 접근할 수 있다.

 

JPA의 모든 데이터 변경(등록, 수정 ,삭제)은 트랜잭션 안에서 이루어져야 한다. 

조회는 트랜잭션이 없어도 가능하다. 변경의 경우 일반적으로 서비스 계층에서 트랜잭션을 시작하기 때문에 문제가 없다.

하지만 이번 예제에서는 복잡한 비즈니스 로직이 없어서 서비스 계층에서 트랜잭션을 걸지 않았다. 

JPA에서는 데이터 변경시 트랜잭션이 필수다.

따라서 리포지토리에 트랜잭션을 걸어주었고, 강조하자면 일반적으로는 서비스 계층에서 써주는 게 맞다.