JPA + Hibernate에서 “다양한 조건을 넣어서 데이터를 조회”하는 방법은 여러 가지가 있습니다.
상황(단순 / 복잡 / 동적 쿼리 등)에 따라 적절한 방법을 선택해야 해요.
아래는 실무에서 자주 쓰이는 5가지 조회 방식을 단계별로 정리해드릴게요.
🧩 1️⃣ JPQL (JPA Query Language)
SQL과 유사하지만 엔티티 객체 기준으로 조회하는 언어입니다.
SQL처럼 테이블 이름이 아니라 엔티티 이름을 기준으로 작성합니다.
String jpql = "SELECT e FROM Employee e WHERE e.department = :dept AND e.salary > :minSalary"; List<Employee> result = entityManager.createQuery(jpql, Employee.class) .setParameter("dept", "IT") .setParameter("minSalary", 5000) .getResultList();
📌 특징
- SQL과 문법 유사 → 배우기 쉬움
- 컴파일 시점에 문법 오류는 잡히지 않음 (문자열 기반)
- 단순한 조회나 조건 검색에 자주 사용됨
🧩 2️⃣ Criteria API (타입 세이프 방식)
JPQL을 Java 코드로 표현하는 방법입니다.
조건이 동적으로 바뀌는 경우 유용합니다.
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Employee> query = cb.createQuery(Employee.class); Root<Employee> e = query.from(Employee.class); // 조건 생성 Predicate deptCond = cb.equal(e.get("department"), "IT"); Predicate salaryCond = cb.gt(e.get("salary"), 5000); // 조건 결합 query.select(e).where(cb.and(deptCond, salaryCond)); // 실행 List<Employee> result = entityManager.createQuery(query).getResultList();
📌 특징
- 문자열 없이 컴파일 타임 검증 가능
- 동적 쿼리에 적합 (if 조건문으로 Predicate 추가 가능)
- 코드가 길고 복잡함 😅
🧩 3️⃣ Spring Data JPA 메서드 이름 쿼리
Spring Boot 환경이라면 가장 많이 쓰이는 방법입니다.
메서드 이름만으로 자동으로 쿼리를 생성합니다.
public interface EmployeeRepository extends JpaRepository<Employee, Long> { List<Employee> findByDepartmentAndSalaryGreaterThan(String department, int salary); }
호출 예시:
List<Employee> list = employeeRepository.findByDepartmentAndSalaryGreaterThan("IT", 5000);
📌 특징
- 코드 간결, 유지보수 쉬움
- 단순 조건 검색에는 최고
- 복잡한 조건은 한계 있음 (→ @Query나 Querydsl로 대체)
🧩 4️⃣ @Query (JPQL 직접 정의)
리포지토리 메서드에 직접 JPQL을 붙일 수 있습니다.
public interface EmployeeRepository extends JpaRepository<Employee, Long> { @Query("SELECT e FROM Employee e WHERE e.department = :dept AND e.salary > :salary") List<Employee> findByDeptAndSalary(@Param("dept") String dept, @Param("salary") int salary); }
📌 특징
- JPQL 기반으로 SQL보다 간단
- 복잡한 조건, 조인, 정렬 등을 자유롭게 작성 가능
- Native SQL보다 JPA스럽게 유지 가능
🧩 5️⃣ Native Query (SQL 그대로 사용)
DB에 특화된 SQL 문법을 써야 하거나,
성능 최적화를 위해 직접 SQL을 쓰는 방법입니다.
@Query(value = "SELECT * FROM employee WHERE department = :dept AND salary > :salary", nativeQuery = true) List<Employee> findNative(@Param("dept") String dept, @Param("salary") int salary);
📌 특징
- SQL 그대로 사용 가능 → DB 특화 기능 (e.g. LIMIT, JOIN) 활용 가능
- JPA 관리(캐시, 엔티티매핑)는 덜 받음
- 유지보수는 조금 어려움
🧩 6️⃣ Querydsl (실무에서 가장 많이 쓰임)
JPQL + Criteria의 장점을 합친 강력한 타입 세이프 동적 쿼리 도구입니다.
QEmployee e = QEmployee.employee; List<Employee> result = queryFactory .selectFrom(e) .where( e.department.eq("IT"), e.salary.gt(5000) ) .fetch();
📌 특징
- 동적 쿼리에 매우 강함 (BooleanBuilder로 조건 조합 가능)
- IDE 자동완성 지원 → 유지보수 편리
- 대규모 프로젝트에서 JPQL보다 훨씬 깔끔하게 관리 가능
⚙️ 상황별 추천 가이드
상황추천 방법
| 간단한 조건 조회 | Spring Data JPA 메서드 네이밍 |
| 조건이 많거나 동적 | Criteria API / Querydsl |
| 복잡한 조인, 그룹핑 | @Query (JPQL) |
| DB 특화 쿼리 (LIMIT 등) | Native Query |
| 대규모 프로젝트, 유지보수 중시 | ✅ Querydsl |
'Springboot' 카테고리의 다른 글
| Spring Data JPA의 @Query + DTO 생성자 방식 (0) | 2025.11.04 |
|---|---|
| Spring Boot 프로젝트 구조 전체(Entity + Repository + Service + Controller + REST 호출 예시) (0) | 2025.11.04 |
| JPA 메소드명 맵핑 방식 (0) | 2025.11.04 |
| EntityManager (0) | 2025.11.04 |