Spring Boot

[Spring Boot] JPQL, Repository 확장

KrystalJo 2021. 11. 7. 17:40

 

JPQL(Java Persistence Query Langauge)

JPQL(Java Persistence Query Language)는 JPA(Java Persistence API)의 일부로 정의된 플랫폼에 독립적인 객체지행 쿼리 언어이다. JPQL은 관계형 데이터베이스의 엔티티에 대한 쿼리를 만드는데 사용한다.

 

  • SQL : 데이터베이스 테이블을 대상으로 쿼리함
  • JPQL : 엔티티 객체를 대상으로 쿼리함

@Query value안에 사용하는 구문이 JPQL이다. 객체지향쿼리이므로 테이블 대신에 엔티티 클래스를 이용하여 쿼리 결과를 조회한다.

 

 

Repository 확장

Spring Data JPA의 Repository를 확장하기 위해서는 다음과 같은 단계로 처리된다.

  • 쿼리 메서드나 @Query 등으로 처리할 수 없는 기능은 별도의 인터페이스로 설계
  • 별도의 인터페이스에 대한 구현 클래스를 작성한다. 이 때 QuerydslRepositorySupport클래스를 부모 클래스로 사용
  • 구현 클래스에 인터페이스의 기능을 Q도메인 클래스와 JPQLQuery를 이용해서 구현

 

QuerydslRepositorySupport클래스는 Repository 확장을 작성하는데 있어서 가장 중요한 클래스이다.

Spring Data JPA에 포함된 클래스로 Querydsl 라이브러리를 이용해서 직접 무언가를 구현할 때 사용한다.

 

 

Querydsl은 'Q도메인'을 이용하여 복잡한 조합을 이용하여 쿼리를 조회하는 경우에 사용하는 동적쿼리이다.

2021.10.23 - [Spring Boot] - [Spring Boot] Spring Data JPA

 

[Spring Boot] Spring Data JPA

Spring Boot에서 사용되는 Spring Data JPA에 대해서 알아보자. Spring Data JPA 쿼리 메서드 : 메서드의 이름 자체가 쿼리의 구문으로 처리되는 기능 @Query(JPQL) : SQL과 유사하게 엔티티 클래스의 정보를 이.

krystaljo.tistory.com

 

확장하고 싶은 기능을 인터페이스로 선언한다.

이 때 인터페이스 내의 메서드 이름은 가능하면 쿼리 메서드와 구별이 가능하도록 작성해야 한다.

 

1. Repository 확장 인터페이스

package org.zerock.board.repository.search;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.zerock.board.entity.Board;

public interface SearchBoardRepository {

    Board search1();

    Page<Object[]> searchPage(String type, String keyword, Pageable pageable);

}

 

2. Repository 확장구현 클래스 : 인터페이스의 이름 + Impl

package org.zerock.board.repository.search;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.JPQLQuery;
import lombok.extern.log4j.Log4j2;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.zerock.board.entity.*;

import java.util.List;
import java.util.stream.Collectors;

@Log4j2
public class SearchBoardRepositoryImpl extends QuerydslRepositorySupport implements SearchBoardRepository {

    public SearchBoardRepositoryImpl() {
        super(Board.class);
    }

    @Override
    public Board search1() {
        log.info("search1........................");

       QBoard board = QBoard.board;
       QReply reply = QReply.reply;
       QMember member = QMember.member;

       JPQLQuery<Board> jpqlQuery = from(board);
       jpqlQuery.leftJoin(member).on(board.writer.eq(member));
       jpqlQuery.leftJoin(reply).on(reply.board.eq(board));


       JPQLQuery<Tuple> tuple = jpqlQuery.select(board, member.email, reply.count())
                       .groupBy(board);
       log.info("-----------------------------");
       log.info(jpqlQuery);
       log.info("-----------------------------");

       List<Board> result = jpqlQuery.fetch();

       return null;
    }

    @Override
    public Page<Object[]> searchPage(String type, String keyword, Pageable pageable){
        log.info("searchPage ....");
        
        return null;
    }

}

 

SearchBoardRepositoryImpl 클래스에서 가장 중요한 점은 QuerydslRepositorySupport 클래스를 상속해야 한다는 점이다. QuerydslRepositorySupport는 생성자가 존재하므로 클래스 내에서 super()를 이용해서 호출해야 한다.

super(Board.class); 도메인 엔티티 클래스를 슈퍼타입인 QuerydslRepositorySupport 생성자의 인자로 넘겨줘야 한다.

 

search1()메소드를 보면 QBoard, QReply, QMember Q 도메인을 선언하고, JPQLQuery 인터페이스를 활용하여 Querydsl을 실행

 

 3. 도메인 Repository - Repository 확장 인터페이스 를 상속해야함

package org.zerock.board.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import org.zerock.board.entity.Board;
import org.zerock.board.repository.search.SearchBoardRepository;

import java.util.List;

public interface BoardRepository extends JpaRepository<Board, Long>, SearchBoardRepository  {


}

 

 

 

출처:https://adrenal.tistory.com/25

 

 

 

 

 

'Spring Boot' 카테고리의 다른 글

[Spring Boot]ResponseEntity  (0) 2021.11.28
[Spring Boot] Spring Data JPA  (0) 2021.10.23
[Spring Boot] RedirectAttributes, FlashAttributes  (0) 2021.10.01
[Spring Boot] Entity VS DTO  (0) 2021.09.25