240703
학습
● 1. QueryDSL 사용법
QueryDSL이란?
1. SQL, JPQL 등을 코드로 작성할 수 있도록 해주는 프레임워크이다.
2. 쿼리를 type-safe(컴파일시 에러 체크 가능)하게 Java코드로 작성을 할 수 있게 도와준다.
SpringDataJPA는 복잡한 쿼리, 동적 쿼리 등을 구현하는데 있어 한계가 존재하며 MyBatis, JPQL과 같은 문자열 형태로 쿼리문을 작성하게 되면 컴파일 시에 오류를 발견하는 것이 불가능하다는 큰 단점이 존재했다.
이러한 문제점을 해결하기 위해 Querydsl을 이용할 수 있다. 해당 Querydsl은 자바 코드로 SQL문을 작성할 수 있기 때문에 컴파일시에 오류 확인이 가능하여 잘못된 쿼리가 실행되는 것을 미리 방지를 할 수 있다.
QueryDSL 예제 코드
String username = "user1";
return jpaQueryFactory.select(user)
.select(user)
.from(user)
.where(user.username.eq(username))
.fetch();
위와 같이 빌더패턴을 이용하여 쿼리문을 작성해서 최종적으로 fetch()메서드를 통해 쿼리를 실행하게 된다.
( 이러한 방식 덕분에 컴파일 시점에 에러를 확실하게 잡아줄 수 있다.)
QueryDSL 설정
QueryDSL 프로젝트 환경
- SpringBoot 3.3.0.ver
- gradle 8.8.ver
- java 17.ver
1. build.gradle 세팅
dependencies {
// querydsl 설정 추가
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
// 컴파일 시점에 별도의 객체를 만들어 그 객체를 이용해 코드 형태로 SQL문을 짜주기 때문에 필수 설정
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}
// Querydsl 설정부
def generated = 'src/main/generated'
// querydsl QClass 파일 생성 위치를 지정
tasks.withType(JavaCompile) {
options.getGeneratedSourceOutputDirectory().set(file(generated))
}
// java source set 에 querydsl QClass 위치 추가
sourceSets {
main.java.srcDirs += [ generated ]
}
// gradle clean 시에 QClass 디렉토리 삭제
clean {
delete file(generated)
}
jar {
enabled = false
}
2. QueryDSL 빈등록 설정 파일 세팅
@Configuration
public class QueryDslConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
1. @PersistenceContext 애너테이션을 이용하여 EntityManager를 빈으로 주입을 해주는 과정
2. JPAQueryFactory를 Bean으로 등록하면서 EntityManager Bean객체를 넣어주는 과정
3. QueryDSL 인터페이스 및 구현 클래스
// 1. JpaRepository에서 이용하기 위한 interface
@Repository
public interface BoardRepositoryCustom {
List<User> getUserList(String category); // 임의로 메서드를 추가했음.
}
// 2. 1번에 만든 인터페이스의 구현클래스
@Repository
@RequiredArgsConstructor
public class UserRepositoryImpl implements UserRepositoryCustom {
private final JPAQueryFactory jpaQueryFactory;
@Override
public List<ProductEntity> getBoardList(String category) {
QBoard board = QBoard.board;
return jpaQueryFactory.select(board)
.from(board)
.where(board.category.eq(category)) // 카테고리에 맞는 게시글
.fetch();
}
해당 인터페이스는 밑에 보여줄 JpaRepository에서 사용을 하게 되며 해당 인터페이스를 구현한 클래스를 만들어줘야한다. 구현 클래스를 통해 DB에 쿼리문을 날리게 된다.
4. JpaRepository
@Repository
public interface BoardRepository extends JpaRepository<Board, Long>, BoardRepositoryCustom {
}
최종적으로 JpaRepository가 직접 만든 인터페이스를 상속받아 이용을 하게 된다.
5. Service 로직
@Service
@RequiredArgsConstructor
public class BoardService {
private final BoardRepository boardRepository;
public List<BoardResponse> getBoardList(String category) {
// 오버라이딩 되어있는 구현클래스의 메서드를 호출하여 로직을 수행 후 list반환
List<Board> boardList = productRepository.getBoardList(category);
// 반복문 및 스트림을 이용하여 BoardResponse에 담아 리턴하는 로직
// **
return **;
}
}
BoardRepository는 JpaRepository와 Custom인터페이스를 상속받고 있어 Custom인터페이스의 구현클래스를 이용하여 QueryDSL을 이용할 수 있게 된다.
회고
오늘은 QueryDSL를 세팅하는 방법과 QueryDSL을 사용하는 방법을 학습을 했고, N+1의 문제에 대해서 알게 되었다.
'내일배움캠프 Spring 5기' 카테고리의 다른 글
내일배움캠프 56일차 TIL - AWS(3) RDS (0) | 2024.07.04 |
---|---|
내일배움캠프 55일차 TIL - QueryDSL Pagination (0) | 2024.07.04 |
내일배움캠프 53일차 TIL - 면접 예상 질의 응답 (0) | 2024.07.02 |
내일배움캠프 52일차 TIL - AWS(2) EC2 (0) | 2024.07.01 |
내일배움캠프 51일차 TIL - AWS(1) (0) | 2024.06.28 |