Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- jwt메서드
- 인텔리제이
- REST API 규칙
- Q 클래스
- json gson 차이
- Error creating bean with name
- Unsatisfied dependency
- git
- jpa회원가입
- spring서버
- uncheck Exception
- 최종 프로젝트
- 스프링 부트 공식 문서
- 빈생성안됨
- 1차캐시
- 복합키
- jpa에러
- json
- Spring Spring boot 차이
- 스프링 부트 기능
- REST란
- @IdClass
- 스프링부트오류
- Filter
- JoinColumn
- JPA
- github
- queryDSL
- JPA주의사항
- ERD 작성
Archives
- Today
- Total
Everyday Dev System
QueryDsl 기초 본문
참조 : 내배캠 JPA 심화 강의 자료
https://teamsparta.notion.site/SpringData-QueryDSL-85b57e18a5204e70b6035a319d63f866
오류 시 해결
1. QChannel 이 활성화가 안될 경우 main 메서드가 있는 클래스를 다시 실행.
2. 테스트 코드시 Repository의 Bean 생성이 안될 경우에는
1) main 메서드가 있는 클래스에 아래 어노테이션 기재 여부 확인
@SpringBootApplication
@EnableJpaRepositories
2) 그럼에도 안 될 경우에는 테스트 코드에 @SpringBootTest 어노테이션이 명시되어있는지 확인
3) 그래도 안된다면, Repository 클래스에 상속한 클래( JpaRepository, QuerydslPredicateExecutor ) 의
<> 안의 파라미터 클래스가 Entity로 매핑이 잘 되는지 확인.
4) 그럼에도 안된다면, 재빌드 혹은 재부팅 혹은 IDEA 껐다가 다시 켜기
QueryDSl을 Spring boot 3.0 버전부터는 의존성만 추가하면 사용이 가능해졌다.
사용 방법
- 프로그래밍되어 제공되는 쿼리명 규칙
- 리턴타입 {접두어}{도입부}By{프로퍼티 표현식}(조건식)(And|Or){프로퍼티 표현식}(조건식) (매개변수...)
위치 | Query명 |
접두어 | Find, Get, Query, Count, ... |
도입부 | Distinct, First(N), Top(N) |
프로퍼티 표현식 | Person.Address.ZipCode => find(Person)ByAddress_ZipCode(...) |
조건식 | IgnoreCase, Between, LessThan, GreaterThan, Like, Contains, ... |
정렬 조건 | OrderBy{프로퍼티}Asc|Desc |
리턴 타입 | E, Optional<E>, List<E>, Page<E>, Slice<E>, Stream<E> |
매개변수 | Pageable, Sort |
// 기본
List<User> findByNameAndPassword(String name, String password);
// distinct (중복제거)
List<User> findDistinctUserByNameOrPassword(String name, String password);
List<User> findUserDistinctByNameOrPassword(String name, String password);
// ignoring case (대소문자 무시)
List<User> findByNameIgnoreCase(String name);
List<User> findByNameAndPasswordAllIgnoreCase(String name, String password);
// 정렬
List<Person> findByNameOrderByNameAsc(String name);
List<Person> findByNameOrderByNameDesc(String name);
// 페이징
Page<User> findByName(String name, Pageable pageable); // Page 는 카운트쿼리 수행됨
Slice<User> findByName(String name, Pageable pageable); // Slice 는 카운트쿼리 수행안됨
List<User> findByName(String name, Sort sort);
List<User> findByName(String name, Pageable pageable);
// 스트림 (stream 다쓴후 자원 해제 해줘야하므로 try with resource 사용추천)
Stream<User> readAllByNameNotNull();
원리
의존성을 추가하면 Spring Data 에 의해 QueryDslPredicateExecuter 인터페이스가 추가가 된다.
이는 JpaRepository가 QueryDsl이 실행이 가능하도록 인터페이스를 제공한다.
기능
- QueryDSL의 Predicate 인터페이스로 조건문을 여러개를 구성하여 따로 관리할 수 있다.
- findOne(Predicate), findAll(Predicate) 주로 이 2개 메소드가 사용된다.
- findOne = Optional<T> 리턴
- findAll = List<T> | Page<T> | Iterable<T> | Slice<T> 리턴
- findOne(Predicate), findAll(Predicate) 주로 이 2개 메소드가 사용된다.
- Type Safe 기능
- 조건문 구성시에 사용되는 객체, 필드 조건이 실제 타입과 일치한지 체크해준다.
장점
- 문자가 아닌 코드로 쿼리를 작성함으로써, 컴파일 시점에 문법 오류를 쉽게 확인할 수 있다.
- 자동 완성 등 IDE의 도움을 받을 수 있다.
- 동적인 쿼리 작성이 편리하다.
- 쿼리 작성 시 제약 조건 등을 메서드 추출을 통해 재사용할 수 있다.
의존성 추가 후 재빌드 및 main 실행
아래 의존성을 build.gradle 에 추가를 한다.
// 9. QueryDSL 적용을 위한 의존성 (SpringBoot3.0 부터는 jakarta 사용해야함)
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
예시 코드
ChannelRepository 에서 QueryDsl을 사용한다고 치면, 아래와 같이
QuerydslPredicateExecutor<Channel> 을 상속받아야 한다.
package me.chaeyoung.jpa.channel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
public interface ChannelRepository extends JpaRepository<Channel, Long>,
QuerydslPredicateExecutor<Channel> {
}
ChannelRepository 의 다이어그램을 살펴보면 아래과 같다.
JpaRepository 와 QuerydslPredicateExecutor를 상속받았다.
테스트 코드를 실행해보자.
Channel 테이블에 name 칼럼값이 "chaeyoung"인 레코드를 insert 해보았다.
그 후, name 칼럼값이 "CHAEYOUNG"와 일치한 레코드를 조회하는 테스트이다.
package me.chaeyoung.jpa.channel;
import com.querydsl.core.types.Predicate;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;
@SpringBootTest
@Transactional
@Rollback(value = false)
class ChannelRepositoryTest {
@Autowired
private ChannelRepository channelRepository;
@Test
void queryDslTest() {
// given
var newChannel = Channel.builder().name("chaeyoung").build();
channelRepository.save(newChannel);
Predicate predicate = QChannel.channel
.name.equalsIgnoreCase("CHAEYOUNG");
// when
Optional<Channel> optional = channelRepository.findOne(predicate);
// then
assert optional.get().getName().equals(newChannel.getName());
}
}
QueryDsl을 잘 활용하여 테스트가 성공했다.
'내배캠 주요 학습 > JPA 심화' 카테고리의 다른 글
Auditing 활용하기 (1) | 2023.08.01 |
---|---|
QueryDSL 활용 코드 (0) | 2023.08.01 |
Repository 에 기능 추가하기 (0) | 2023.07.31 |
JpaRepository 기능 제한하기 (0) | 2023.07.31 |
Cascade.REMOVE 와 orphanRemoval=true 차이 (0) | 2023.07.31 |