querydsl 21

SQL function 호출하기

SQL function은 JPA와 같이 Dialect에 등록된 내용만 호출할 수 있다.(JPQL VS Querydsl 둘다 호출 가능) SQL function을 한 번 호출해보자. member -> M으로 변경 replace 함수 사용 @Test public void sqlFunction() { List result = queryFactory .select(Expressions.stringTemplate( "function('replace', {0}, {1}, {2})", // member라는 단어를 M으로 바꿔서 member.username, "member", "M")) .from(member) .fetch(); for (String s : result) { System.out.println("s = ..

Spring/QueryDSL 2022.04.21

수정, 삭제 벌크 연산 - 배치 쿼리

쿼리 한번으로 대량의 데이터를 수정할 때 사용한다. JPA는 기본적으로 엔티티를 가지고 와서 엔티티의 값만 바꾸면 트랜잭션 commit할 때 flush가 일어나면서(변경 감지) 엔티티가 바뀐걸 감지하고 업데이트 쿼리가 만들어지고 db에 업데이트 쿼리가 나가게 된다. 모든 개발자의 연봉 50% 인상해 => 쿼리 한번에 날리고 트랜잭션 커밋하는게 낫다. 실행을 시키고 h2 db에서 확인을 해보면 아래와 같이 나오게 된다. @Test @Commit public void bulkUpdate() { // member1 = 10 -> 비회원 // member2 = 20 -> 비회원 // member3 = 30 -> 유지 // member4 = 40 -> 유지 long count = queryFactory .upda..

Spring/QueryDSL 2022.04.21

동적 쿼리 - Where 다중 파라미터 사용

굉장히 유용하니 잘 알아두도록 하자. 앞서 했던 BooleanBuilder와 같은 기능을 하지만 코드가 다르다. 아래 코드에서 where절에 null이 들어가면 어떻게 될까? // QuerydslBasicTest @Test public void dynamicQuery_WhereParam() { String usernameParam = "member1"; Integer ageParam = 10; List result = searchMember2(usernameParam, ageParam); assertThat(result.size()).isEqualTo(1); } private List searchMember2(String usernameCond, Integer ageCond) { return queryF..

Spring/QueryDSL 2022.04.21

동적 쿼리 - BooleanBuilder

동적 쿼리를 해결하는 두가지 방식 BooleanBuilder Where 다중 파라미터 사용 BooleanBuilder을 써보면 파라미터 두개를 넣었기 때문에 동적쿼리에서 둘 다 결과가 조회 되어야 한다. @Test public void dynamicQuery_BooleanBuilder() { // username이 1이고 나이가 10살인 사람을 찾으려 한다. String usernameParam = "member1"; Integer ageParam = 10; List result = searchMember1(usernameParam, ageParam); assertThat(result.size()).isEqualTo(1); } // 파라미터의 값이 null이냐 아니냐에 따라서 동적으로 바뀌게 된다. pr..

Spring/QueryDSL 2022.04.21

프로젝션과 결과 반환 - @QueryProjection

궁극의 방법 QueryProjection 그것을 알아보자! MemberDto에다가 바로 QueryProjection이라고 적어주자, @Data @NoArgsConstructor public class MemberDto { // username이랑 age 두개만 최적화해서 가져오고 싶다해서 MemberDto를 만들어줌 private String username; private int age; @QueryProjection public MemberDto(String username, int age) { this.username = username; this.age = age; } 그리고 gradle 파일에가서 compileQuerydsl을 눌러주면 dto도 Q파일로 생성이 된다. Test에서는 아래와 같이 ..

Spring/QueryDSL 2022.04.21

프로젝션 결과 반환 - DTO 조회

먼저 순수 JPA에서 DTO로 조회하는 방법을 알아보자. // MemberDto package study.querydsl.dto; import lombok.Data; @Data public class MemberDto { // username이랑 age 두개만 최적화해서 가져오고 싶다해서 MemberDto를 만들어줌 private String username; private int age; public MemberDto(String username, int age) { this.username = username; this.age = age; } } Test에서 JPQL에서는 아래와 같이 짜야 한다. // QuerydslBasicTest @Test public void findDtoByJPQL() { /..

Spring/QueryDSL 2022.04.21

프로젝션과 결과 반환 - 기본

프로젝션: select 대상 지정 프로젝션 대상이 하나 단순하게 사용자의 이름만 가져오게 되면 반환타입이 String으로 나오게 된다. 프로젝션 대상이 하나면 타입을 명확하게 지정할 수 있다 프로잭션 대상이 둘 이상이면 튜플이나 DTO로 조회 튜플은 Querydsl이 여러개를 조회할 때 만들어 놓은 타입이 있다. @Test public void simpleProjection() { // username 타입과 맞는 것만 result 에 나온다. // List 도 프로젝션 대상의 하나다. List result = queryFactory .select(member.username) .from(member) .fetch(); for (String s : result) { System.out.println("s..

Spring/QueryDSL 2022.04.20

Case 문 & 상수, 문자 더하기

JPA가 지원하는 CASE 문은 Querydsl에서도 다 지원이 된다. 단순한 조건 부터 먼저 test 돌려보자. @Test public void basicCase() { List result = queryFactory .select(member.age .when(10).then("열살") .when(20).then("스무살") .otherwise("기타")) .from(member) .fetch(); for (String s : result) { System.out.println("s = " + s); } } s = 열살 s = 스무살 s = 기타 s = 기타 복잡한 조건을 돌려보면 @Test public void complexCase() { List result = queryFactory // 복잡할..

Spring/QueryDSL 2022.04.20

서브 쿼리

쿼리안에 쿼리를 넣는작업을 해보자 com.querydsl.jpa.JPAExpressions 사용 나이가 가장 많은 회원을 조회해보면 /** * 나이가 가장 많은 회원 조회 */ @Test public void subQuery() { QMember memberSub = new QMember("memberSub"); List result = queryFactory // member 테이블을 가져오고 .selectFrom(member) // member의 나이가 같은데 .where(member.age.eq( // member의 나이가 가장 큰사람이랑 같다. => 40이라는 값이 나올꺼다 JPAExpressions .select(memberSub.age.max()) .from(memberSub) )) .fetc..

Spring/QueryDSL 2022.04.20

조인 - 페치 조인

페치 조인은 SQL에서 제공하는 기능은 아니고 SQL조인 활용해서 연관된 엔티티 SQL 한번에 조회하는 기능이다. 주로 성능 최적화에 사용하는 방법 Member에 team은 lazy로 세팅 // 연관관계(team과의 연관관계)의 주인은 여기 => JPA 완벽히 숙지 // ManyToOne은 항상 fetch를 lazy로 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id") private Team team; fetchjoin test를 돌려보면 @Test public void fetchJoinNo() { // 데이터를 깔끔하게 지우자. // fetchjoin 테스트 할 때는 영속성 컨텍스트에 남아있는 거 안지워주면 결과를 제대로 못본다. // 영..

Spring/QueryDSL 2022.04.20