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, 없으면 false

existsByCrtPartyIdAndOriginalResocIdAndIsSharedAndHistEndDate 사용 목적

중복 공유 방지를 위해 사용합니다:

  // 상황: 조직 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 = true

6. 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 작성 필요
  • 오타나 문법 오류 가능성

+ Recent posts