ㅇ 동적쿼리란
실행 시점에 쿼리의 내용이 동적으로 생성되는 SQL쿼리. 입력이나 특정 조건에 따라 쿼리의 일부 또는 전체가 달라지는 쿼리.
String sql = "SELECT * FROM Users WHERE 1=1";
if (name != null) {
sql += " AND name = '" + name + "'";
}
if (age != null) {
sql += " AND age = " + age;
}
위의 코드에선 name이 null이 아니고, age가 null이 아니면,
최종 코드는
"SELECT * FROM Users WHERE 1=1 AND name = ' ㅇㅇㅇ ' AND age = ㅇㅇ'"
이렇게 작성된다.
ㅇ SpringDataJpa의 동적쿼리
Jpa에서 쿼리를 작성해야할땐 JPQL을 사용한다. 물론 네이티브쿼리를 사용할 수 도 있지만 단점들이 많다.
1. 플랫폼 종속성 : 데이터베이스별로 SQL문법이 다 다르기 때문에 한 데이터베이스에 종속되므로 추후에 데이터베이스를 교체하면 한줄한줄 교체하게 되어 이식성이 떨어진다.
2. 타입안전성 부족 : JPQL 또는 Criteria API를 사용하면 컴파일 시점에 쿼리의 타입을 체크할 수 있지만, 네이티브 쿼리는 문자열로 작성되어 컴파일 타임에 쿼리의 타입을 체크할 수 없다. 오직 런타임시점에만 오류를 발견할 수 있다.
이런 이유들 때문에 네이티브쿼리는 사용하면 안된다.
이제 Spring Data JPA에서 동적 쿼리를 어떻게 작성할까?
1. Spring Data JPA는 메서드 이름을 기반으로 쿼리를 자동으로 생성해준다.
List<User> findByUsernameAndStatus(String username, Status status);
이렇게 하다보면 이름이 너무 길어져서 좋지않다.
2. @Query에너테이션을 사용해 JPQL쿼리
@Query("SELECT u FROM User u WHERE u.username = :username AND u.status = :status")
List<User> findByUsernameAndStatus(@Param("username") String username, @Param("status") Status status);
이런식으로 동적쿼리를 짤 수 있지만 완전히 동적인 쿼리를 작성하기엔 힘들다.
3. Example , ExampleMatcher를 사용한 동적 쿼리
User user = new User();
user.setUsername("john");
Example<User> example = Example.of(user, ExampleMatcher.matching().withIgnorePaths("status"));
List<User> users = userRepository.findAll(example);
Query by Example을 사용하면 엔티티의 샘플 객체를 기반으로 검색 조건을 생성할 순 있다.
ㅇ 결론
QueryDSL을 쓰자.
'Java > ORM' 카테고리의 다른 글
JAVA ORM - Spring Data JPA(웹 페이징,정렬) (0) | 2024.08.27 |
---|---|
JAVA ORM - Spring Data JPA(사용자 정의 리포지토리, Auditing의 두가지 방법) (0) | 2024.08.25 |
JAVA ORM - Spring Data JPA(페이징, 슬라이스, countQuery) (0) | 2024.08.23 |
JAVA ORM - Spring Data JPA(JpaRepository의 주요 메서드, 쿼리 메서드) (0) | 2024.08.21 |
JAVA ORM - Spring Data JPA(JPA와의 차이점) (0) | 2024.08.20 |