[스프링] 스프링 Data Jpa(7) 사용자 정의 리포지토리 구현
·
스프링 데이터 JPA
스프링 데이터 JPA는 정말 편리하다. 인터페이스만 선언해도 기본적인 CRUD는 물론이고, 메서드 이름만으로 쿼리를 자동 생성해주는 기능까지 제공한다.하지만 모든 상황이 이렇게만 해결되는 건 아니다.프로젝트를 진행하다 보면, 복잡한 동적 쿼리라든가 비즈니스에 특화된 로직이 필요할 때가 생긴다. 이런 경우 단순히 JpaRepository 인터페이스만으로는 한계가 있다. 그렇다고 리포지토리 인터페이스에 선언된 수많은 메서드를 직접 전부 구현하기에는 너무 복잡하고 사실상 불가능에 가깝다. 그래서 필요한 것이 바로 사용자 정의 리포지토리(Custom Repository) 기능이다. 1. 문제 상황: 직접 구현한다면?public interface MemberRepository extends JpaReposito..
[스프링] 스프링 Data JPA(6) @EntityGraph
·
스프링 데이터 JPA
JPA를 사용하다 보면 가장 자주 겪는 성능 문제 중 하나가 바로 N+1 문제다.회원(Member)과 팀(Team)이 지연 로딩 관계라고 할 때, 단순히 회원 목록을 조회했는데 이후 각 회원의 팀을 가져오는 순간마다 추가 쿼리가 실행된다. 회원이 100명이라면 1(회원 조회) + 100(팀 조회) = 101번의 SQL이 실행되는 꼴이다. 작은 데이터에서는 체감이 안 될 수 있지만, 실제 서비스에서는 쿼리 폭발로 이어져 치명적인 성능 문제가 된다. N+1 문제 예시@Testpublic void findMemberLazy() throws Exception { Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); teamReposi..
[스프링] 스프링 Data JPA(5) 벌크성 수정쿼리
·
스프링 데이터 JPA
이번 글에서는 스프링 데이터 JPA에서 벌크성 수정 쿼리를 어떻게 다루는지 살펴본다.일반적인 엔티티 수정은 JPA가 영속성 컨텍스트를 관리하면서 Dirty Checking(변경 감지)을 통해 자동으로 update 쿼리를 실행한다.하지만 대량의 데이터를 한 번에 수정해야 할 때는 이런 방식이 비효율적이다. 엔티티를 전부 조회해서 1건씩 변경하는 것은 메모리와 쿼리 성능 모두에 큰 부담이 된다.이럴 때 필요한 것이 바로 벌크성 수정 쿼리다. 1. 순수 JPA에서 벌크성 수정 쿼리순수 JPA에서는 EntityManager.createQuery()를 통해 직접 벌크 update 쿼리를 실행할 수 있다.public int bulkAgePlus(int age) { int resultCount = em.crea..
[스프링] 스프링 Data JPA(4) JPA 페이징과 정렬
·
스프링 데이터 JPA
이번 글에서는 JPA에서 페이징과 정렬을 어떻게 처리하는지 살펴본다.먼저 순수 JPA로 페이징을 구현해보고, 그다음 스프링 데이터 JPA로 같은 기능을 얼마나 간단히 처리할 수 있는지 비교해보자. 1. 순수 JPA에서의 페이징과 정렬검색 조건: 나이 = 10정렬 조건: 이름 내림차순페이징 조건: 첫 번째 페이지, 페이지당 3건 리포지토리 코드public List findByPage(int age, int offset, int limit) { return em.createQuery("select m from Member m where m.age = :age order by m.username desc") .setParameter("age", age) .setFi..
[스프링] 스프링 Data JPA(3) @Query, 리포지토리 메소드에 쿼리 정의하기
·
스프링 데이터 JPA
이번 글에서는 스프링 데이터 JPA의 @Query를 이용해 리포지토리 메소드에 쿼리를 직접 정의하는 방법을 살펴본다.“원래 JPA로 코드를 짠다면 어떻게 될까?”라는 비교에서 시작해 보자. 1. 순수 JPA로 작성했을 때public List findUser(String username, int age) { return em.createQuery( "select m from Member m where m.username = :username and m.age = :age", Member.class) .setParameter("username", username) .setParameter("age", age) .getResu..
[스프링] 스프링 Data JPA(2) 메소드 이름으로 쿼리생성
·
스프링 데이터 JPA
지난 시간에는 스프링 데이터 JPA가 기본적으로 제공하는 간단한 메소드들을 살펴보았다.그렇다면 이번에는 “특정 이름을 가진 회원 중 나이가 15살보다 많은 사람만 찾고 싶을 때” 어떻게 하면 될까? 순수 JPA 방식순수 JPA로 작성한다면 JPQL을 직접 써야 한다.public List findByUsernameAndAgeGreaterThan(String username, int age) { return em.createQuery("select m from Member m where m.username = :username and m.age > :age", Member.class) .setParameter("username", username) .setPa..