@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는 선언한 "도메인 클래스 + .(점) + 메서드 이름"으로 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>