728x90
반응형
QueryDSL이란?
Spring Boot Data JPA 는 쿼리문을 직접 짜지 않아도 함수명만 알맞게 적어주면
쿼리를 자동으로 짜주는 ORM으로 유명한데 사실상 조금만 복잡하고 동적인 쿼리를 짜려고만 해도
JPQL등을 통해 쿼리를 직접 짜야하는 불상사가 발생하고 만다.
이러한 불편함을 줄여주고자 자바만 알아도 쿼리를 대신 짜주는 프레임워크가 있는데
이를 QueryDSL 이라고 부른다.
쿼리가 아니라 자바 기반이라서 컴파일 시점에 오류 발견이 가능하고, 자동완성도 지원하여 실무에서도 많이 사용되고 있다. 필자도 QueryDSL을 사용해보고 싶었지만 진입장벽이 있는 것 같아서 망설이다가 블로그에 글을 쓸 핑계로 공부를 해보고 알아낸 내용을 공유해보려고 한다.
1. 개발환경 맞추기
1-1 generate 해서 인텔리제이로 열기
2. build.gradle에 QueryDSL 프레임워크 적용하기
PROJECT: Gradle
Boot: 2.7.5
JAVA: 17
DBMS: H2 (테스트용)
plugins {
id 'org.springframework.boot' version '2.7.5'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'java'
}
group = 'com.QueryDSL'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation group: 'com.querydsl', name: 'querydsl-jpa', version: '5.0.0'
implementation group: 'com.querydsl', name: 'querydsl-core', version: '5.0.0'
implementation group: 'com.querydsl', name: 'querydsl-apt', version: '5.0.0'
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jpa"
annotationProcessor("jakarta.persistence:jakarta.persistence-api")
annotationProcessor("jakarta.annotation:jakarta.annotation-api")
// QueryDSL
sourceSets {
main {
java {
srcDirs = ["$projectDir/src/main/java"]
}
}
}
}
tasks.named('test') {
useJUnitPlatform()
}
3. QueryDSL Config 파일 생성하기
package com.QueryDSL.Drill;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Configuration
public class QuerydslConfiguration {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
4. 일반 도메인=엔티티 생성하기
package com.QueryDSL.Drill.entity;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Employees {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String address;
@Builder
public Employees(String name, String address) {
this.name = name;
this.address = address;
}
@Override
public String toString() {
return '\n'+"직원 명단 {" + '\n'+
" 순서 = " + id + '\n'+
", 이름 = " + name + '\n'+'\''+
", 주소 = " + address + '\n'+ '\'' +
'}';
}
}
5. QueryDSL 전용 엔티티 생성하기
5-1
5-2
5-3
위 그림처럼 기본 엔티니를 기반으로 쿼리DSL 전용 엔티티가 build->generated 안에 생성됨
클릭해보면 static으로 인스턴스화 되어있는것을 확인 할 수 있음
6. REPOSITORY
6-1 기본 JPA Repository 생성하기
package com.QueryDSL.Drill.repository;
import com.QueryDSL.Drill.entity.Employees;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends JpaRepository<Employees, Long> {
}
6-2 QueryDSL 전용 Repository 생성하기
package com.QueryDSL.Drill.repository;
import com.QueryDSL.Drill.entity.Employees;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.List;
import static com.QueryDSL.Drill.entity.QEmployees.employees;
@RequiredArgsConstructor
@Repository
public class EmployeeRepositorySupport {
private final JPAQueryFactory queryFactory;
public List<Employees> findByName(String name) {
return queryFactory
.selectFrom(employees)
.where(employees.name.eq(name))
.fetch();
}
public List<Employees> findAll() {
return queryFactory
.selectFrom(employees)
.fetch();
}
}
6-3
아래 그림처럼 빨간줄이 떠있는 employees 를 static import 하기 (빨간줄에 alt+enter OR 마우스 hover)
7. 테스트 하기
package com.QueryDSL.Drill;
import com.QueryDSL.Drill.entity.Employees;
import com.QueryDSL.Drill.repository.EmployeeRepository;
import com.QueryDSL.Drill.repository.EmployeeRepositorySupport;
import org.junit.After;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
class DrillApplicationTests {
@Autowired
private EmployeeRepository employeeRepository;
@Autowired
private EmployeeRepositorySupport employeeRepositorySupport;
@After
public void tearDown() throws Exception {
employeeRepository.deleteAllInBatch();
}
@Test
public void querydsl_기본_기능_확인() {
//given
employeeRepository.save(new Employees("보라돌이", "서울"));
employeeRepository.save(new Employees("뚜비", "부산"));
employeeRepository.save(new Employees("나나", "제주도"));
//when
List<Employees> selectOne = employeeRepositorySupport.findByName("보라돌이");
List<Employees> selectAll = employeeRepositorySupport.findAll();
//then
System.out.println("--------한명만 조회하기------- " + selectOne);
System.out.println("--------모두 조회하기-------- " + selectAll);
}
}
결과
728x90
반응형
'개발자 전향 프로젝트' 카테고리의 다른 글
프레임워크와 라이브러리의 차이가 뭔가요? [ 면접 질문 ] (0) | 2022.10.29 |
---|---|
[SpringBoot Data JPA] 중복은 있을 수 없어 -1 (0) | 2022.10.26 |
유효성 검사(?)로 클라이언트를 막아보자 - 1 (0) | 2022.10.20 |
소소한 팁 -2 제 버튼은 왜 submit이 아닌데 submit이 되죠? (0) | 2022.10.20 |
싱글톤이 무엇인가요? (0) | 2022.10.20 |