Spring Data Jpa

yeezze·2022년 7월 8일
0

개념

Spring에서 사용되는 DB 접근 기술 중 하나
repository에 구현체 없이 인터페이스만으로 개발이 가능하다.
기본적인 CRUD 제공

기본 메소드 : https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html

기본 제공 메소드가 아닐 경우에도 스프링 데이터 JPA가 메소드 이름을 분석해서 JPQL을 실행

주요 메소드

  • save() : 새로운 엔티티는 저장하고 이미 있는 경우 update
  • delete() : 삭제
  • findAll() : 모든 엔티티 조회 (sort, pageable 조건을 파라미터로 제공_)
  • findOne() : 엔티티 하나를 조회

쿼리 메소드 기능

  • 인터페이스에 메소드만 선언하면 해당 메소드의 이름으로 적절한 JPQL 쿼리를 생성해서 실행

1. 메소드 이름으로 쿼리 생성

공식 문서


2. JPA NamedQuery 호출

  • 쿼리에 이름을 부여해서 사용
  • 어노테이션이나 XML에 쿼리를 정의
@Entity
@NamedQuery(
	name = "Member.findByUsername",
    query = "select m from Member m where m.username = :username")
public class Member {
	
}

JPA를 직접 사용해서 Named 쿼리 호출

public class MemberReposiory {

	public List<Member> findByUsername(String username) {
    	List<Member> resultList = 
        	em.createNamedQuery("Member.findByUsername", Member.class)
            	.setParameter("username", "회원1")
                .getResultList();
    }
}

스프링 데이터 JPA로 Named 쿼리 호출

public interface MemberRepository extends JpaRepository<Member, Long> { 

	List<Member> findByUsername(@Param("username") String username);
}

3. 직접 쿼리를 정의하고 싶을 경우 @Query 사용

  • 애플리케이션 실행 시점에 문법 오류를 발견할 수 있는 장점
public interface MemberRepository extends JpaRepository<Member, Long> {
	
    // 이름 기반 파라미터 바인딩
    @Query("select m from Member m where m.username = :name",
    	nativeQuery = true)
    Member findByUsername(@Param("name") String username);
}

벌크성 수정 쿼리

개념

  • 특정 하나가 아닌 다수의 데이터를 수정하는 쿼리
  • JPA에서는 데이터 수정 시 '변경감지'를 통해 값을 수정한다.
  • 변경 데이터가 많을 때 굳이 하나씩 '변경감지'를 일으켜서 수정하면 비효율적!
  • 순수 JPA를 사용하며 em.createQuery(...).executeUpdate()를 사용해서 벌크성 수정 쿼리를 사용한다.
  • 스프링 데이터 JPA에서는 이러한 벌크성 수정 쿼리를 편리하게 사용하기 위한 방법을 제공한다.

age 이상의 나이를 가진 Member의 나이를 모두 update

순수 JPA

public int agePlus(int age) {
	return em.createQuery("update Member m set m.age = m.age+1 where m.age >= :age")
    	.setParameter("age", age)
        .executeUpdate();
  • update 쿼리 작성 후에 반드시 executeUpdate()를 통해 실행
    -> 반영된 레코드의 수를 반환

스프링 데이터 JPA

// executeUpdate를 실행하기 위한 어노테이션
@Modifying(clearAutomatically = true)
@Query("update Member m set m.age = m.age+1 where m.age >= :age")
int agePlus(@Param("age") int age);
  • JpaRepository를 상속받는 인터페이스에 @Query를 통해 JPQL을 작성한 것
  • @Modifying을 사용해서 조회를 위한 getResultList()나 getSingleResult()가 아닌 exeCuteUpdate()가 실행되도록 지정!
  • 벌크성 수정 쿼리에는 반드시 @Modifying이 있어야 한다 -> 없으면 QueryExecutionRequestException 오류 발생

@Modifying 사용시 주의점

  • 벌크성 수정 / 삭제 쿼리는 영속성 컨텍스트를 거치지 않고 수행된다
    -> 기존에 영속성 컨텍스트에 남아있는 데이터와 불일치를 발생시킬 수 있다
  • 벌크성 수정 / 삭제 쿼리를 한 후에는 반드시 영속성 컨텍스트를 초기화 시켜야 한다 (혹은 영속성 컨텍스트로 엔티티가 관리되기 전에 수행해도 괜찮다)
  • 순수 JPA Repository라면 em.flush() / em.clear()를 해야하지만 스프링 데이터 JPA는 이러한 기능을 옵션으로 제공
    --> @Modifying(clearAutomatically = true)

출처

profile
백엔드 개발자 😊

0개의 댓글