@Entity
@Getter @Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"id", "username", "age"})
@NamedQuery(
    name="Member.findByUsername",
    query="select m from Member m where m.username = :username")
public class Member extends BaseEntity{

	 @Id
	 @GeneratedValue
	 @Column(name = "member_id")
	 private Long id;
	 private String username;
	 private int age;

	 @ManyToOne(fetch = FetchType.LAZY)
	 @JoinColumn(name = "team_id")
	 private Team team;
}

@NoArgsConstructor AccessLevel.PROTECTED: 기본 생성자 막고 싶은데, JPA 스팩상 PROTECTED로 열어두어야 함

org.springframework.data.repository.Repository 를 구현한 클래스는 스캔 대상

→ memberRepository.getClass() class com.sun.proxy.$ProxyXXX

쿼리 메소드 기능

쿼리 메소드 기능 3가지

public interface MemberRepository extends JpaRepository<Member, Long> {
	 List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}

<aside> <img src="/icons/code_green.svg" alt="/icons/code_green.svg" width="40px" />

https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html

</aside>

JPA NamedQuery

스프링 데이터 JPA는 선언한 "도메인 클래스 + .(점) + 메서드 이름"으로 Named 쿼리를 찾아서 실행

만약 실행할 Named 쿼리가 없으면 메서드 이름으로 쿼리 생성 전략을 사용한다.

필요하면 전략을 변경할 수 있지만 권장하지 않는다.

@NamedQuery(
    name="Member.findByUsername",
    query="select m from Member m where m.username = :username")
public class Member extends BaseEntity{}

===

public interface MemberRepository extends JpaRepository<Member, Long> { //** 여기 선언한 Member 도메인 클래스
	 List<Member> findByUsername(@Param("username") String username);
} 

<aside> <img src="/icons/code_green.svg" alt="/icons/code_green.svg" width="40px" />

참고: 스프링 데이터 JPA를 사용하면 실무에서 Named Query를 직접 등록해서 사용하는 일은 드물다. 대신 @Query 를 사용해서 리파지토리 메소드에 쿼리를 직접 정의한다.

</aside>

@Query, 리포지토리 메소드에 쿼리 정의하기