FireDrago

[Spring] JPA 사용하기 본문

카테고리 없음

[Spring] JPA 사용하기

화이용 2024. 3. 8. 12:17

SQL Mapper 기술로는 JDBCTemplate , MyBatis 등이 대표적이다.

그런데 SQLMapper 기술은 개발자가 직접 SQL을 입력해야한다. 

반면에 ORM 기술은 SQL을 대신 작성해준다. 생산성이 훨씬 더 커지는 것이다.
JPA는 자바 표준 ORM 인터페이스이고 대표적인 구현체로 Hibernate가 있다.

기본적인 JPA의 사용법을 알아보자

 

1. 기본 설정하기

build.gradle에 JPA 추가
applicaiton.properties에 JPA 설정

 

build.gradle에 의존 관계를 추가하고, application.properties에 다음과 같이 설정해주자

test도 설정파일이 있다면 동일하게 설정하자

 logging.level.org.hibernate.SQL=DEBUG JPA의 여러 구현체중 Hibernate 가 자동으로 생성하는 SQL을 보여준다.
logging.level.org.hibernate.orm.jdbc.bind = TRACE SQL에 바인딩되는 파라미터를 확인 할 수 있다.

 

 

2. 도메인 객체 설정

@Entity JPA 가 도메인 객체를 인식할 수 있게 해준다.
@Id Pk와 해당 필드를 맵핑한다.
@GeneratedValue
(strategy = GenerationType.IDENTITY)
PK 값을 DB가 자동 생성하는 IDENTITY 방식을 사용한다.
Insert 시에 DB가 생성한 값을 자동으로 Item.setId( ) 로 넣어준다.
@Column(name = "칼럼명", length = ) 칼럼과 객체 필드를 맵핑한다. 스프링 부트는 카멜표기와 스네이크 표기 변환한다.
위 코드의 경우는 생략해도 크게 문제없다. 객체필드와 컬럼명이 다를경우 설정필요
length 속성은 테이블 생성시 컬럼의 길이값을 제공하는 역할을 한다.
JPA는 테이블 생성기능도 지원한다.
public Item() {} JPA는 public , protected 기본 생성자가 반드시 필요하다.

 

 

 

3. JPA 적용하기

도메인객체를 바탕으로 Repository  객체에서 JPA를 사용해보자

@Repository @Repository 는 컴포넌트 스캔 + JPA 예외변환 AOP 적용 기능을 제공한다.
@Transcational JPA의 모든 데이터변경 (삽입, 수정, 삭제)시 트랜잭션 기반으로 동작한다.
@Transactional 스프링 AOP를 이용하여 트랜잭션 기능을 구현한다.
EntityManager JPA는 EntityManager 객체를 사용하여 기능을 수행한다. 
의존성주입을 설정해줬다면, 스프링이 자동으로 생성한다.
내부에 DataSource를 가지고 있고 데이터베이스에 접근할 수 있다.

 

<save ( ) - 데이터 저장>

em.persist(item) 도메인 설정해준 Item 객체를 파라미터로 persist 메서드를 호출한다.
테스트 실행 로그를 보면, SQL을 자동으로 생성하여 실행한것을 볼 수 있다.

이때 id가 없는데 insert를 실행한 후 db가 생성한 값을 item.id 에 자동으로 등록한다.
 Item 객체에서 @GenerateValue를 설정해두었기 때문이다.

 

 

<findById( ) - 단건 조회>

em.find (클래스, pk값) find 메서드를 사용하면 JPA가 반환클래스 형태로 pk값을 통해 SQL을 만들어 조회하고
객체를 반환해준다.

 

 

<update( ) - 데이터 수정>

 

업데이트의 경우 JPA 사용이 조금 특이하다. 코드를 보면, 마치 자바를 사용하듯이 조회한 findItem 객체에 필드값을 

담기만하고 업데이트를 수행하는 메서드가 없다. 

JPA는 트랜잭션이 커밋되는 시점에 엔터티에 변화가 있는지 확인하고, 변화가 있다면 UPDATE SQL을 실행한다.

그런데 테스트 코드 로그에서는 UPDATE SQL이 없다. 테스트에 @Transaction 이 적용되어 있어, 커밋대신 롤백이 되기에

UPDATE SQL이 실행되지 않았다. SQL을 보고싶다면 @Commit 애너테이션을 붙이면 된다.

 

<findAll - 목록조회>

TypeQuery<Item> query = em.createQuery( JPQL, 반환클래스)  
query.setParameter(변수명, 파라미터 값) Jpql에 설정한 네임 파라미터에 값을 넣는다.
query.getResultList() 쿼리 결과값을 List<Item>으로 받아온다.

코드 초반에 JPQL 이 사용되었다. JPQL은 객체지향 쿼리언어이다. 복잡한 조건으로 조회할때 사용한다.

이 코드를 보면 JPA도 동적 쿼리 작성이 쉽지 않다는 것을 알 수 있다. 그래서 QueryDSL을 함께 사용한다.

동적 쿼리를 생성한 뒤에 파라미터를 입력한다.  :maxPrice  로 파라미터를 설정한 다음

setParameter() 메서드로 파라미터 바인딩을 한다.

 

 

JPA 예외변환

 

EntityManager 는 JPA 기술이고 JPA 예외를 발생시킨다. 이때 @Repository 애너테이션이 있으면 

스프링은 스프링예외로 변환하는 AOP를 만들어준다.

 

JPA 예외 : PersistenceException 과 그 하위 예외 , IllegalStateException, IllegalArgumentException