QueryDSL 조회방법 3가지!
1. 결과가 하나일 때 -> 바로 지정하기 -> List<String>
@Test
public void simpleProjection() {
List<String> result = queryFactory
.select(member.username)
.from(member)
.fetch();
for (String s : result) {
System.out.println("result = " + result);
}
}
2. 결과가 둘 이상일 경우 Tuple을 사용 -> List<Tuple>
* 레포지토리 안에서만 사용하기 -> 다른곳에서 사용할려면 dto를 통해서 담아서 보내기
@Test
public void selectSubQuery() {
QMember memberSub = new QMember("memberSub");
List<Tuple> result = queryFactory
.select(member.username,
select(memberSub.age.avg())
.from(memberSub))
.from(member)
.fetch();
for (Tuple tuple : result) {
System.out.println("tuple = " + tuple);
}
}
3. Dto 조회
ⓐ 순수 JPA -> new 오퍼레이션(폴더주소)
@Test
public void findDtoByJPQL(){
List<MemberDto> result = em.createQuery("select new study.querydsl.dto.MemberDto(m.username, m.age) from Member m", MemberDto.class)
.getResultList();
for (MemberDto memberDto : result) {
System.out.println("memberDto = " + memberDto);
}
}
ⓑ QueryDSL 3가지 방법!
ㄱ. 프로퍼티 접근 - Setter
@Test
public void findDtoBySetter() {
List<MemberDto> result = queryFactory
.select(Projections.bean(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
for (MemberDto memberDto : result) {
System.out.println("memberDto = " + memberDto);
}
}
ㄴ. 필드 직접 접근
@Test
public void findDtoByField() {
List<MemberDto> result = queryFactory
.select(Projections.fields(MemberDto.class,
member.username,
member.age))
.from(member)
.fetch();
for (MemberDto memberDto : result) {
System.out.println("memberDto = " + memberDto);
}
}
ㄷ. 생성자 사용
@Test
public void findUserDto() {
QMember memberSub = new QMember("memberSub");
List<UserDto> result = queryFactory
.select(Projections.fields(UserDto.class,
ExpressionUtils.as(member.username, "name"),
ExpressionUtils.as(JPAExpressions
.select(memberSub.age.max())
.from(memberSub), "age")
))
.from(member)
.fetch();
for (UserDto userDto : result){
System.out.println("userDto = " + userDto);
}
}
package study.querydsl.dto;
import lombok.Data;
@Data
public class UserDto {
private String name;
private int age;
public UserDto() {
}
public UserDto(String name, int age) {
this.name = name;
this.age = age;
}
}
* @QuryProjection
Dto도 Q파일로생성
(Gradle -> orther -> compileQuerydsl을 눌러서 dto에대한 Q파일생성 - 어노테이션을 사용해야 함)
-> 다른 방법들에 비해서, 빼먹은 내용을 검사해 주기때문에 가장 안전함
단점)
1. Q파일을 생성해야 됨
2. DTO에 @QueryProjection을 넣어줘야 함
-> Dto자체가 쿼리 DSL에 의존성을 갖게됨 -> 라이브러리를 제거할 때 영향을 받음
순수하지 않음 : 단순히 어노테이션을 제거하면 되지만, 전체 서비스에서 사용되다보니 서비스에 영향을 받게 됨
package study.querydsl.dto;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class MemberDto {
private String username;
private int age;
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
}
@Test
public void findDtoByQueryProjection() {
List<MemberDto> result = queryFactory
.select(new QMemberDto(member.username, member.age))
.from(member)
.fetch();
for (MemberDto memberDto : result) {
System.out.println("memberDto = " + memberDto);
}
}
'공부 > QueryDSL' 카테고리의 다른 글
QueryDSL 공부하기 - 3 (0) | 2022.05.11 |
---|---|
QueryDSL 공부하기 - 2 (0) | 2022.05.11 |
QueryDSL 공부하기 - 1 (0) | 2022.05.10 |