spring boot JPQL 적용.

형기브·2023년 7월 25일
0

SPRING

목록 보기
3/3

정의

JPQL(Java Persistence Query Languag)는 테이블이 아닌 객체를 대상으로 쿼리를 사용할 수 있는 방법이다.

먼저 짚고 넘어가야할 부분은 JPQL은 select from join 같은 sql문법과 관련된 단어는 대소문자를 구분하지 않지만 객체나 변수등은 대소문자를 구분해 주어야한다.

그리고 alias를 반드시 적어 주어야한다. as는 생략 가능하다.

적용

지금까지 jpa에서 제공하는 query method방식만 사용했는데 프로젝트를 하면서 검색기능을 구현해야해서 query method방식으로는 제약이 있다고 생각해 jqpl을 사용해보기로 했다.

JPA와 차이점.

public interface UserRepository extends JpaRepository<User,String> {
	List<User> findAllById(Long Id);
}

기본적으로 query method를 사용하기 위해서는 인터페이스로 레포지토리를 만들고 간편하게 JpaRepository를 상속받으면 미리 정의되어있는 method들을 사용할 수 있다.


JPQL은 인터페이스로 구현했을 때는 @Query 어노테이션을 사용한다.

@Query("SELECT u FROM User u WHERE u.id = :id")
    User findById(Long id);

콜론(:)을 사용해서 파라미터로 넘어온 값을 저장해준다.


클래스로 구현했을 때는 Entitymagager를 사용해야한다.

@Repository
public class PinRepository {
    @PersistenceContext
    private EntityManager entityManager;
    
    public List<Pin> findAllByOrderByCreatedAtDesc() {
        String jpql = "SELECT p FROM Pin p " +
                "ORDER BY p.createdAt DESC";
        return entityManager.createQuery(jpql, Pin.class)
                .getResultList();
    }
    
    public List<Pin> searchPinsByKeywordWithPriority(String keyword) {
        String jpql = "SELECT p FROM Pin p " +
                "WHERE p.title LIKE :keyword OR p.content LIKE :keyword " +
                "ORDER BY CASE WHEN p.title LIKE :keyword AND p.content LIKE :keyword THEN 1 " +
                "              WHEN p.title LIKE :keyword THEN 2 " +
                "              WHEN p.content LIKE :keyword THEN 3" +
                "              ELSE 4 " +
                "         END, p.createdAt DESC";
        List<Pin> pinsWithKeyword = entityManager.createQuery(jpql, Pin.class)
                .setParameter("keyword", "%" + keyword + "%")
                .getResultList();

        jpql = "SELECT p FROM Pin p " +
                "WHERE p.title not LIKE :keyword AND p.content not LIKE :keyword " +
                "ORDER BY p.createdAt DESC";
        List<Pin> pinsWithoutKeyword = entityManager.createQuery(jpql, Pin.class)
                .setParameter("keyword", "%" + keyword + "%")
                .getResultList();

        List<Pin> result = new ArrayList<>();
        result.addAll(pinsWithKeyword);
        result.addAll(pinsWithoutKeyword);
        return result;
    }
    
}

keyword로 간단한 검색기능을 구현한 코드를 가져와봤다.

findAllByOrderByCreatedAtDesc()은 query method와 비교하기 쉽도록 메소드명을 query method와 같이 정했다.

jpql = "SELECT p FROM Pin p " +
                "WHERE p.title not LIKE ?1 AND p.content not LIKE ?1 " +
                "ORDER BY p.createdAt DESC";
        List<Pin> pinsWithoutKeyword = entityManager.createQuery(jpql, Pin.class)
                .setParameter( 1 , "%" + keyword + "%")
                .getResultList();

이 전에는 콜론(:)으로 파라미터가 들어갈 곳을 지정해줬는데 ?를 사용해서 위치기준으로 파라미터를 넣어 줄 수도 있다.


public List<Pin> findAllByOrderByCreatedAtDescByDto() {
        String jpql = 
        		"SELECT new (페키지경로).PinResponseDto(p.id, p.image.image) FROM Pin p " +
                "ORDER BY p.createdAt DESC";
        return entityManager.createQuery(jpql, Pin.class)
                .getResultList();
    }

그리고 이렇게 Dto로 반환해야할 경우 query문 안에 new로 생성해서 생성자 파라미터로 물론 객체와 관련된 필드를 불러올 수 있다.

간단하게 JPQL에 대해서 알아보았고

다음에는 query DSL에 도전해 봐야겠다.

profile
Slow but Steady

0개의 댓글