1. Spring Data JPA Query Method란 ?
메서드 이름만으로 자동으로 쿼리를 생성해주는 기능
// Repository 인터페이스에 메서드 선언만 하면
boolean existsByCrtPartyIdAndOriginalResocIdAndIsSharedAndHistEndDate(
BigDecimal crtPartyId,
BigDecimal originalResocId,
String isShared,
LocalDateTime histEndDate
);
// Spring Data JPA가 자동으로 SQL을 생성하여 실행2. 메서드 이름 분석
메서드 이름은 규칙에 따라 구성됩니다:
existsBy + CrtPartyId + And + OriginalResocId + And + IsShared + And + HistEndDate
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
동작 + 필드명 + 조건 + 필드명 + 조건 + 필드명 + 조건 + 필드명
각 부분 설명:
| 부분 | 의미 | 설명 |
|---|---|---|
| exists | 존재 여부 확인 | 해당 조건의 레코드가 있으면 true, 없으면 false |
| By | 조건 시작 | WHERE 절 시작 |
| CrtPartyId | 필드명 | ResocMstr.crtPartyId |
| And | 논리 연산자 | SQL의 AND |
| OriginalResocId | 필드명 | ResocMstr.originalResocId |
| And | 논리 연산자 | SQL의 AND |
| IsShared | 필드명 | ResocMstr.isShared |
| And | 논리 연산자 | SQL의 AND |
| HistEndDate | 필드명 | ResocMstr.histEndDate |
3. 자동 생성되는 SQL
SELECT
CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END
FROM chatbi.resoc_mstr
WHERE crt_party_id = ? -- 첫 번째 파라미터
AND original_resoc_id = ? -- 두 번째 파라미터
AND is_shared = ? -- 세 번째 파라미터
AND hist_end_date = ? -- 네 번째 파라미터4. 실제 동작 예시
// Service에서 호출
private boolean isDuplicateShare(BigDecimal originalResocId, BigDecimal targetOrgId) {
return resocMstrRepository.existsByCrtPartyIdAndOriginalResocIdAndIsSharedAndHistEndDate(
targetOrgId, // crtPartyId = 10
originalResocId, // originalResocId = 100
"Y", // isShared = 'Y'
MAX_HIST_END_DATE // histEndDate = '9999-12-31'
);
}
// 실행되는 SQL
// SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END
// FROM resoc_mstr
// WHERE crt_party_id = 10
// AND original_resoc_id = 100
// AND is_shared = 'Y'
// AND hist_end_date = '9999-12-31 00:00:00'
// 결과: 레코드가 존재하면 true, 없으면 falseexistsByCrtPartyIdAndOriginalResocIdAndIsSharedAndHistEndDate 사용 목적
중복 공유 방지를 위해 사용합니다:
// 상황: 조직 10에게 메뉴 100을 공유하려고 함
// 체크 로직
boolean isDuplicate = isDuplicateShare(100, 10);
if (isDuplicate) {
// 이미 조직 10에게 메뉴 100(또는 그 복사본)이 공유되어 있음
// → 재공유 방지
throw new DuplicateShareException("이미 공유된 자원입니다.");
} // 데이터 예시
// resoc_mstr 테이블:
// resoc_id | crt_party_id | original_resoc_id | is_shared | hist_end_date
// ---------|--------------|-------------------|-----------|---------------
// 500 | 10 | 100 | Y | 9999-12-31 ← 이미 존재!
//
// → isDuplicate = true6. Query Method의 다른 예시
// 1. 단순 조회
List findByCrtPartyId(BigDecimal crtPartyId);
// → WHERE crt_party_id = ?
// 2. 정렬
List findByCrtPartyIdOrderBySortSeq(BigDecimal crtPartyId);
// → WHERE crt_party_id = ? ORDER BY sort_seq
// 3. 범위 조회
List findByResocIdBetween(BigDecimal start, BigDecimal end);
// → WHERE resoc_id BETWEEN ? AND ?
// 4. Like 검색
List findByResocNameContaining(String keyword);
// → WHERE resoc_name LIKE %?%
// 5. Count
long countByCrtPartyIdAndIsShared(BigDecimal crtPartyId, String isShared);
// → SELECT COUNT(*) WHERE crt_party_id = ? AND is_shared = ?
7. Query Method vs @Query
Query Method (자동 생성)
boolean existsByCrtPartyIdAndOriginalResocId(
BigDecimal crtPartyId,
BigDecimal originalResocId
);
장점:
- 구현 불필요, 선언만 하면 됨
- 타입 안정성 보장
- 메서드 이름으로 의도 명확
- 단점:
- 복잡한 쿼리는 메서드 이름이 너무 길어짐
- Join이나 서브쿼리 등 복잡한 로직 구현 어려움@Query("""
SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END
FROM ResocMstr r
WHERE r.crtPartyId = :crtPartyId""")
boolean checkDuplicateShare(
@Param("crtPartyId") BigDecimal crtPartyId,
@Param("originalResocId") BigDecimal originalResocId,
@Param("isShared") String isShared
); - 장점:
AND r.originalResocId = :originalResocId AND r.isShared = :isShared- @Query (수동 작성)
- 복잡한 쿼리 작성 가능
- Join, 서브쿼리, 집계 함수 등 자유롭게 사용
- 단점:
- 직접 JPQL/SQL 작성 필요
- 오타나 문법 오류 가능성
'#개발 > JPA' 카테고리의 다른 글
| JPA 메서드 네이밍 규칙 (0) | 2025.10.31 |
|---|