#14 - JPA 실무 가이드 3부: 메소드 자동 생성과 조회 패턴의 모든 것
중년개발자
@loxo
24일 전
JPA 실무 가이드 3부: 메소드 자동 생성과 조회 패턴의 모든 것
"쿼리를 안 쓴다고? 아니다. 이름으로 쿼리를 작성하는 것이다."
1. JPA Repository의 본질
많은 사람들이 착각한다.
“JPA는 쿼리를 안 써도 된다”
❌ 틀렸다.
정확한 표현은 이거다.
“쿼리를 코드가 아니라 ‘메소드 이름’으로 작성한다”
Spring Data JPA는
Repository 인터페이스만 정의하면
👉 내부적으로 JPQL을 자동 생성한다.
2. 가장 기본: CRUD는 이미 다 만들어져 있다
public interface OrderRepository extends JpaRepository<Order, Long> {
}이 한 줄로 이미 다음이 존재한다.
기본 제공 메소드
save(entity) // insert or update
findById(id) // 단건 조회
findAll() // 전체 조회
delete(entity) // 삭제
count() // 개수
existsById(id) // 존재 여부👉 실무에서 가장 많이 쓰는 TOP 5
savefindByIdfindAllexistsByIddelete
3. 핵심: “메소드 이름으로 쿼리를 만든다”
JPA의 진짜 시작은 여기다.
3.1 가장 기본 패턴
Optional<Order> findByOrderNumber(String orderNumber);👉 생성되는 쿼리
SELECT o FROM Order o WHERE o.orderNumber = ?3.2 And / Or 조건
List<Order> findByStatusAndMemberId(String status, Long memberId);WHERE status = ? AND member_id = ?3.3 비교 연산
List<Order> findByPriceGreaterThan(int price);
List<Order> findByPriceLessThanEqual(int price);3.4 Like / 포함 검색
List<Order> findByNameContaining(String keyword);
List<Order> findByNameStartingWith(String prefix);
List<Order> findByNameEndingWith(String suffix);3.5 정렬 포함
List<Order> findByStatusOrderByCreatedAtDesc(String status);3.6 Top / First (LIMIT)
List<Order> findTop10ByStatusOrderByCreatedAtDesc(String status);👉 실무에서 매우 많이 사용됨 (최근 데이터 조회)
4. 실무에서 진짜 많이 쓰는 패턴 TOP 7
이건 그냥 외우는 게 아니라
👉 몸에 익혀야 한다
4.1 존재 여부 체크 (가장 중요)
boolean existsByEmail(String email);👉 로그인 / 중복 체크 필수 패턴
4.2 단건 조회 + Optional
Optional<Member> findByEmail(String email);👉 null 방지 + 안정성
4.3 목록 조회
List<Order> findByMemberId(Long memberId);4.4 상태 기반 조회
List<Order> findByStatus(String status);👉 거의 모든 서비스에서 등장
4.5 기간 조회
List<Order> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);4.6 최신 데이터 조회
List<Order> findTop5ByOrderByCreatedAtDesc();4.7 페이징 (실무 필수)
Page<Order> findByStatus(String status, Pageable pageable);👉 내부적으로 limit + offset 처리
5. 연관관계 필드 조회 (중요 포인트)
List<Order> findByMemberId(Long memberId);여기서 많은 사람이 헷갈린다.
memberId는 필드가 아닌데 왜 되지?
👉 이유:
@ManyToOne
private Member member;JPA는 자동으로 해석한다.
member.id → memberId👉 즉,
findByMemberId는 내부적으로
WHERE member.id = ?로 변환된다.
6. 네이밍 규칙 핵심 정리
구조
find + By + 필드 + 조건 + And/Or + 필드 + 조건
자주 쓰는 키워드
| 키워드 | 의미 |
|---|---|
And | AND |
Or | OR |
Between | 범위 |
LessThan | < |
GreaterThan | > |
Like | LIKE |
Containing | %검색% |
In | IN |
OrderBy | 정렬 |
7. 언제 “이걸 쓰면 안 되는가”
여기서부터가 실무 레벨 차이다.
❌ 조건이 많아질 때
findByStatusAndTypeAndCategoryAndRegionAndCreatedAtBetween(...)👉 가독성 붕괴
❌ 복잡한 조인
👉 이건 이미 JPA 영역이 아니다
❌ 동적 쿼리
👉 조건이 바뀌는 순간 끝
8. 그래서 등장하는 것
이 지점에서 자연스럽게 이어진다.
QueryDSL / JPQL / Native Query
9. 실무 기준 최종 결론
✔ JPA 메소드 자동 생성은 어디까지?
- 단순 조회 → ✅ 적극 사용
- 조건 2~3개 → ✅ OK
- 페이징 → ✅ 필수
- 존재 여부 → ✅ 매우 중요
❌ 이 이상이면
👉 QueryDSL로 넘어가라
🔥 이 파트의 핵심 한 줄
“JPA는 쿼리를 안 쓰는 기술이 아니라, 쿼리를 숨기는 기술이다.”
-
JPA 메소드는 “빠르게 만드는 도구”
-
QueryDSL은 “정확하게 만드는 도구”
💡 실무 팁: 이 구간부터는 직접 메소드를 작성하는 것보다 도구의 도움을 받는 것이 훨씬 효율적이다. -
IntelliJ 플러그인인 JPA Buddy 등을 사용하면
- Repository 메소드 자동 생성
- JPQL / QueryDSL 코드 생성
- 엔티티 관계 시각화
👉 즉, "손으로 작성"하는 영역이 아니라
👉 도구를 활용해 생산성을 끌어올리는 구간이다.