내일배움캠프 Spring 56일차(목) TIL - JPQL 및 QueryDSL 활용

Skadi·2024년 3월 14일
0

JPQL 및 QueryDSL 활용

1. JPQL

1-1 EntityMananger.createQuery()

  • 쿼리 문자열과 Entity 를 직접 넣어서 쿼리를 작성한다.
  • setParameter 와 같이 key, value 문자열을 통해서 쿼리 파라미터를 매핑할 수 있다.
@Test
	public void testEmCreateQuery() {
		String qlString = "select u from User u " +
							"where u.username = :username";

		Member findUser = em.createQuery(qlString, User.class)
				.setParameter("username", "yummy")
				.getSingleResult();

		assertThat(findUser.getUsername()).isEqualTo("yummy");
	}

1-2 @Qeury (repository interface)

  • @Query 의 인자값으로 간단하게 쿼리를 작성할 수 있습니다.
    • 쿼리를 작성할때는 테이블명이 아니라 Entity 명으로 조회하게 됩니다.
  • 변수 바인딩은 2가지 방법으로 할 수 있습니다.
// ?변수순번 사용
  public interface UserRepository extends JpaRepository<User, Long> {

    @Query("SELECT u, u.password AS customField FROM User u WHERE u.username = ?1")
    List<User> findByUsernameWithCustomField(String username, Sort sort);


    @Query("SELECT u FROM User u WHERE u.username = ?1")
    List<User> findByUsername(String username, Sort sort);
  }
  
// :변수명 사용
public interface UserRepository extends JpaRepository<User, Long> {

  @Query("SELECT u, u.password AS customField FROM User u WHERE u.username = :username")
  List<User> findByUsernameWithCustomField(String username, Sort sort);


  @Query("SELECT u FROM User u WHERE u.username = :username")
  List<User> findByUsername(String username, Sort sort);
}

2. QueryDSL (JPAQueryFactory)

  • Entity 의 매핑정보를 활용하여 쿼리에 적합하도록 쿼리 전용 클래스(Q클래스)로 재구성해주는 기술
  • 여기에 JPAQueryFactory 을 통한 Q클래스를 활용할 수 있는 기능들을 제공한다.
  • 그럼, JPAQueryFactory 는 뭐야?
    • 재구성한 Q클래스를 통해 문자열이 아닌 객체 또는 함수로 쿼리를 작성하고 실행하게 해주는 기술
@PersistenceContext
EntityManager em;
 
public List<User> selectUserByUsernameAndPassword(String username, String password){
	JPAQueryFactory jqf = new JPAQueryFactory(em);
	QUser user = QUser.user;
  
	List<Person> userList = jpf
								.selectFrom(user)
								.where(person.username.eq(username)
									.and(person.password.eq(password))
								.fetch();
                                
	return userList;
}

JPQL과 @Query의 주요 차이점

  • JPQL은 EntityManager를 통해 실행되며, 동적 쿼리 생성에 유연성을 제공합니다. 복잡한 쿼리를 작성하거나, 쿼리 실행 조건이 런타임에 결정되어야 하는 경우 유리할 수 있습니다. JPQL은 직접 문자열로 쿼리를 작성하기 때문에, 오타나 쿼리 오류를 컴파일 시점이 아닌 런타임 시점에 발견하게 됩니다.

  • @Query 어노테이션은 리포지토리 인터페이스에 쿼리를 직접 명시할 수 있게 해주며, 개발자가 직접 작성한 쿼리를 통해 데이터베이스를 조작할 수 있습니다. 이 방법은 쿼리를 미리 정의하고 관리하기 쉽게 해주며, 간단한 쿼리에서 효율적입니다. 그러나 동적 쿼리 생성은 지원하지 않으며, 쿼리의 복잡성이 증가할수록 관리하기 어려울 수 있습니다.

QueryDSL의 주요 장점

  • 타입 안정성: QueryDSL은 컴파일 시점에 쿼리의 문법 오류를 검출할 수 있게 해주므로, 개발자가 더 안정적으로 쿼리를 작성할 수 있게 합니다. 이는 JPQL이나 @Query 어노테이션에서 문자열 기반으로 쿼리를 작성할 때 발생할 수 있는 오타나 문법 오류를 사전에 방지할 수 있게 해줍니다.

  • 동적 쿼리: QueryDSL은 동적 쿼리를 손쉽게 작성할 수 있게 해주는 다양한 API를 제공합니다. 이는 복잡한 조건에 따라 쿼리를 유연하게 변경해야 하는 경우 매우 유용합니다.

  • 가독성: QueryDSL은 메소드 체이닝을 통한 쿼리 작성을 지원하므로, 쿼리의 의도를 코드 자체에서 쉽게 파악할 수 있습니다. 이로 인해 코드의 가독성이 향상되며 유지 보수가 용이해집니다.

결론

JPQL, @Query, QueryDSL은 각각의 사용 사례와 선호도에 따라 선택할 수 있습니다. 간단하고 정적인 쿼리는 @Query로 충분할 수 있으며, 동적 쿼리나 복잡한 로직을 다루어야 하는 경우 JPQL이나 QueryDSL을 고려할 수 있습니다. QueryDSL은 특히 타입 안정성과 가독성 측면에서 많은 장점을 제공하므로, 복잡한 쿼리를 다루는 대규모 프로젝트에서 선호될 수 있습니다.

0개의 댓글