본문 바로가기

CS 잡지식

쿼리 메서드(Feat.Spring Data JPA)

public interface MemberReposiotry extends JpaRepository<Member,Long> {
	
	// List<Member> findByusername(String username);
	
}

Spring Data JPA에 대한 OverView (tistory.com)

 

Spring Data JPA에 대한 OverView

Spring Data JPA -> Spring Framework와 JPA이란 기반 위에서, [JPA]를 정말 편리하게 사용할 수 있게 해주는 Spring에서 제공하는 라이브 러리이다. 우리가 여태껏 복잡하게 순수 JPA만으로 개발해 왔던 Repositor

jbluke.tistory.com

위 사이트의 [스프링 데이터]와 [스프링 데이터 JPA]의 Hierarchy를 보면, 개발자가 원하는 거의 모~~든 API들이 다 있다.

그러나, MemberRepository에서 [회원 이름](username)을 가지고 Member를 찾는 API는 없다. 

특정 [도메인]을 이용한 API이므로, 그러한 것까지 API로는 만들어 놓지를 못한다. 

그렇다고 MemberRepository 인터페이스에 List<Member> findByusername(String username)을 직접 추가

하여, 개발자가 [직접] 구현을 하고 된다면 [스프링 데이터]와 [스프링 데이터 JPA]의 Hierarchy에 존재하는 몇 백개의 API

에 대해서도 개발자가 직접 일일이 다 정의를 해줘야 하므로, 사실상 이 방법은 불가능에 가깝다. 

-> Spring Data JPA는 [쿼리 메서드]라는 기능을 제공하여 위와 같은 [조회] API 구현을 지원한다. 

(쿼리(Query) : [조회]를 하는 메서드)

 

public interface MemberReposiotry extends JpaRepository<Member,Long> {

    //Spring Data JPA가 메서드 명을 보고 아래 [쿼리 메서드]([조회] 메서드)를 자동으로 구현을 해준다.
    //-> findByusernameAndAgeGreaterThan : findById + username + And + Age + Greater Than + (username,age)
    // [username]과 [age Greater Than]은 SELECT문의 WHERE절에 Select Condition으로 들어 가며
    // 매개변수 (username)과 (age)는 바인딩돼서 SQL문이 만들어 진다.
    List<Member> findByusernameAndAgeGreaterThan(String username,int age);

}

List<Member> findByusernameAndAgeGreaterThan(~~)을 구현해 주지 않았는데도, 아래와 같이 사용하였을 때,

정상적으로 작동을 해준다. 

이것이 바로, Spring Data JPA가 제공하는 [쿼리 메서드]([조회] 메서드) 기능이다. 

@Test@Transactional
public void findByusernameAndAgeGreaterThan(){

    Member member1 = new Member("member1", 19);
    Member member2 = new Member("member1", 20);
    Member member3 = new Member("member2", 21);
    Member member4 = new Member("member3", 22);
    Member member5 = new Member("member1", 23);
    repository.save(member1); // repository는 MemberRepository [인터페이스]이다!
    repository.save(member2);
    repository.save(member3);
    repository.save(member4);
    repository.save(member5);

    List<Member> findMember = repository.findByusernameAndAgeGreaterThan("member1",20);

    for (Member member : findMember) {
        assertThat(member.getUsername()).isEqualTo("member1");
        assertThat(member.getAge()).isGreaterThan(20);
    }

    assertThat(findMember.size()).isEqualTo(1);

}

 

쿼리 메서드 작성법의 구체적인 방법은 스프링 공식 메뉴얼을 참조!!!

그러나 Spring Data JPA가 제공하는 쿼리 메서드에는 단점이 존재한다. 

바로, 메서드명이 너무 길다라는 것이다. 

필드명이 2,3개 정도일 때는 어느 정도 감당이 가능하지만, 그 이상일 때에는 오히려 사용 안 하는 것이 좋다. 

-> 위 단점을 해결하기 위하여 또 다른 대안들이 존재를 한다.

EX) a) JPA - NamedQuery(이 방법은 실무에서 거의 사용 안 한다고함) , Spring Data JPA가 제공하는 { b) @Query or

c) [레포지토리 메서드에 바로 쿼리 정의하기] 기법 }을 사용하면 됨. 

-> c) 방법을 거의 사용하지, a),b) 방법은 거의 사용안 함

그 이유와 구체적인 사용법에 대해서 아래 사이트를 참조!

https://jbluke.tistory.com/448

 

@NamedQuery vs @Query( JPA vs Spring Data JPA )

@Entity @NamedQuery( name="Member.findByUsername", //JPQL을 [직접] 작성해야 한다. query="select m from Member m where m.username = :username") public class Member { @Id@GeneratedValue @Column(name = "member_id") private Long id; private String use

jbluke.tistory.com