프로젝션 대상이 하나
List<String> result = queryFactory
.select(member.username)
.from(member)
.fetch();
튜플 조회
List<Tuple> result= queryFactory
.select(member.username,member.age)
.from(member)
.fetch();
MemberDto
@Data
public class MemberDto {
private String username;
private int age;
public MemberDto() {
}
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
}
DTO 조회 코드
List<MemberDto> result = em.createQuery(
"select new study.querydsl.dto.MemberDto(m.username,m.age)" +
"from Member m",MemberDto.class)
.getresultList();
JPA에서는 DTO를 조회할때 new 명령어를 사용해야함프로퍼티 접근 setter
List<MemberDto> result =queryFactory.
select(Projections.bean(MemberDto.class,member.username,member.age))
.from(member)
.fetch();
필드 직접 접근
List<MemberDto> result =queryFactory
.select(Projections.fields(MemberDto.class,member.suername,member.age))
.from(member)
.fetch();
별칭이 다를 때
@Data
public class UserDto {
private String name;
private int age;
public UserDto() {
}
public UserDto(String name, int age) {
this.name = name;
this.age = age;
}
}
List<UserDto> fetch =queryFactory
.select(Projections.fields(UserDto.class,member.username,as("name"),
ExpressionUtils.as(
JPAExpressions
.select(memberSub.age.max())
.from(memberSub),"age"))
.from(member)
.fetch();
ExpressionUtils.as(source,alias): 필드나 서브 쿼리에 별칭 적용username.as("memberName"): 필드에 별칭 적용생성자 사용
List<MemberDto> result =queryFactory
.select(Projections.constructor(MemberDto.class,member.username,member.age))
.from(member)
.fetch();
@Data
public class MemberDto {
private String username;
private int age;
public MemberDto() {
}
@QueryProjection
public MemberDto(String username, int age) {
this.username = username;
this.age = age;
}
}
QMemberDto 생성 확인@QueryProjection 활용
List<MemberDto> result =queryFactory
.select(new QMemberDto(member.username,member.age))
.from(member)
.fetch();
@Test
void dynamicQuery_BooleanBuilder(){
String usernameParam = "member1";
Integer ageParam=10;
List<Member> result = searchMember1(usernameParam,ageParam);
assertThat(result.size()).isEqualTo(1);
}
private List<Member> searchMember1(String usernameParam, Integer ageParam) {
BooleanBuilder builder = new BooleanBuilder();
if(usernameParam!=null){
builder.and(member.username.eq(usernameParam));
}
if(ageParam!=null){
builder.and(member.age.eq(ageParam));
}
return queryFactory.selectFrom(member).where(builder).fetch();
}
BooleanBuilder로 동적쿼리 설정where 다중 파라미터 사용
@Test
void dynamicQuery_whereParam(){
String usernameParam = "member1";
Integer ageParam=10;
List<Member> result = searchMember2(usernameParam,ageParam);
assertThat(result.size()).isEqualTo(1);
}
private List<Member> searchMember2(String usernameParam, Integer ageParam) {
return queryFactory.selectFrom(member)
.where(usernameEq(usernameParam),ageEq(ageParam))
.fetch();
}
private BooleanExpression ageEq(Integer ageParam) {
return ageParam!=null ? member.age.eq(ageParam) : null;
}
private BooleanExpression usernameEq(String usernameParam) {
return usernameParam==null ? null : member.username.eq(usernameParam);
}
where 조건에 null값은 무시조합 가능
private BooleanExpression allEq(String usernameParam, Integer ageParam) {
return usernameEq(usernameParam).and(ageEq(ageParam));
}
쿼리한번으로 대량 데이터 수정
long count = queryFactory.update(member).set(member.username,"비회원")
.where(member.age.lt(28)).execute();
em.flush();
em.clear();
기존 숫자에 더하기/곱하기
long count =queryFactory.update(member).set(member.age,member.age.add(1)).execute();
long count2 =queryFactory.update(member).set(member.age,member.age.multiply(2)).execute();
대용량 삭제
long cnt= queryFactory.delete(member).where(member.age.gt(18)).execute();
출처: https://www.inflearn.com/course/querydsl-%EC%8B%A4%EC%A0%84