Skip to the content.

QueryAdapter 가이드

목적: QueryDSL 기반 조회를 위한 CQRS Query Adapter 구현 가이드


1️⃣ QueryAdapter란?

역할

Query 요청 → QueryDslRepository → Entity → Mapper → Domain 반환

CQRS의 Query(읽기) 담당으로, 조회 요청을 QueryDslRepository에 위임하고 Mapper를 통해 Domain으로 변환하여 반환합니다.

책임

핵심 원칙

Application Layer (UseCase)
  └─ Query Port 호출
      └─ QueryAdapter
            └─ QueryDslRepository
                  └─ JPAQueryFactory
                        └─ DB 조회

2️⃣ 핵심 원칙

원칙 1: 조회만 담당

원칙 2: QueryDslRepository 위임 + Mapper 변환

// ✅ QueryDslRepository 호출 → Mapper 변환 → Domain 반환
public List<Bc> findByCriteria(BcSearchCriteria criteria) {
    List<BcJpaEntity> entities = queryDslRepository.findByCriteria(criteria);
    return entities.stream()
        .map(bcJpaEntityMapper::toDomain)
        .toList();
}

// ❌ JPAQueryFactory 직접 사용 금지
public List<Bc> findByCriteria(BcSearchCriteria criteria) {
    return queryFactory.selectFrom(qBc)...  // 금지!
}

// ❌ DTO 반환 금지 (Domain 반환)
public List<BcDto> findByCriteria(BcSearchCriteria criteria) {  // 금지!
}

원칙 3: Type-Safe Value Objects

// ✅ Value Object 사용 (타입 안전성)
public Optional<Bc> findById(BcId id) {
    return queryDslRepository.findById(id.getValue())
        .map(bcJpaEntityMapper::toDomain);
}

// ❌ 원시 타입 사용 금지
public Optional<Bc> findById(Long id) {  // 금지!
}

원칙 4: Criteria 패턴


3️⃣ 템플릿 코드

기본 템플릿

@Component
public class {Bc}QueryAdapter implements {Bc}QueryPort {

    private final {Bc}QueryDslRepository queryDslRepository;
    private final {Bc}JpaEntityMapper {bc}JpaEntityMapper;

    public {Bc}QueryAdapter(
        {Bc}QueryDslRepository queryDslRepository,
        {Bc}JpaEntityMapper {bc}JpaEntityMapper
    ) {
        this.queryDslRepository = queryDslRepository;
        this.{bc}JpaEntityMapper = {bc}JpaEntityMapper;
    }

    /**
     * ID로 Bc 단건 조회
     *
     * @param id Bc ID
     * @return Bc Domain (Optional)
     */
    @Override
    public Optional<Bc> findById({Bc}Id id) {
        return queryDslRepository.findById(id.getValue())
            .map({bc}JpaEntityMapper::toDomain);
    }

    /**
     * ID로 Bc 존재 여부 확인
     *
     * @param id Bc ID
     * @return 존재 여부
     */
    @Override
    public boolean existsById({Bc}Id id) {
        return findById(id).isPresent();
    }

    /**
     * 검색 조건으로 Bc 목록 조회
     *
     * @param criteria 검색 조건
     * @return Bc Domain 목록
     */
    @Override
    public List<Bc> findByCriteria({Bc}SearchCriteria criteria) {
        List<{Bc}JpaEntity> entities = queryDslRepository.findByCriteria(criteria);
        return entities.stream()
            .map({bc}JpaEntityMapper::toDomain)
            .toList();
    }

    /**
     * 검색 조건으로 Bc 개수 조회
     *
     * @param criteria 검색 조건
     * @return Bc 개수
     */
    @Override
    public long countByCriteria({Bc}SearchCriteria criteria) {
        return queryDslRepository.countByCriteria(criteria);
    }
}

4️⃣ 체크리스트

QueryAdapter 구현 시:


작성자: Development Team 최종 수정일: 2025-11-12 버전: 1.0.0