월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! Querydsl
querydsl dto 변환시 Projection.fields * 전체 컬럼 가져오는 방법 문의 건
안녕하세요 강사님~ 엔티티 -> Dto 로 변환시 Projection.fields 사용할때 해당 컬럼 100~ 200 개가 있다면 명시하기 귀찮을 수 있는데요 컬럼하나하나 명시 하지 않고 엔티티 -> Dto 전체를 매핑 시킬 방법은 없을까요?
- 미해결실전! Querydsl
querydsl에서의 값 타입 컬렉션
영한님 서포터즈님들 안녕하세요 강의에서는 엔티티 끼리의 DTO 변환은 조인을 통해 쉽게 할 수 있는데, querydsl의 프로젝션을 사용해서 DTO를 변환하는 중에 값 타입 컬렉션은 어떻게 할 수 있는지 궁금해서 여쭤보게 됐습니다. 현재 재 코드입니다 Club.class PetSizeType(Enum) EligibleBreed 이제 querydsl을 이용해서 DTO를 변환시키면 not an entity 라는 에러가 발생합니다 일단 값 타입 컬렉션은 entity가 아니기 때문에 해당 에러 로그는 이해가 됩니다 그렇다면 값 타입 컬렉션은 조인도 할 수 없기 때문에 10개의 Club을 가져오려면 select 쿼리가 20개가 나가게 되는데, 이를 최적화하는 방법이 없을까요? 아래의 사진은 하나의 club을 조회할 때 나가는 쿼리입니다! 그리고 제 개인적인 생각으로는 실무에서도 Enum타입을 자주 사용할 것 같은데,, 같은 Enum Type을 저장하기 위해서 따로 엔티티를 만드는 편인가요??(값 타입 컬렉션을 사용하지 않는지 궁금합니다) 감사합니다
- 미해결실전! Querydsl
쿼리 성능에 대하여...
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 영한님, 강의 잘 듣고 있습니다 ㅎㅎ 취준생때 영한님강의로 공부하고, 현재는 취업해서 JPA+Springboot로 실무에 참여하고있어요! [올해의 계약금액을 월별로 조회] 하는 API를 작성해야하는데요테이블관계는 아래와같습니다. (한명이 여러 계약을 가질수 있고, 하나의 계약에 여러개의 입금내역을 가집니다)[사람] 1 : N [계약] 1 : N [입금내역]입금내역을 조회하지만, 조건절에 사람테이블에 있는 컬럼을 사용해야해서 전부 조인을 걸었어요.SELECT ... FROM 사람 INNER JOIN 계약 ON ,,, INNER JOIN 입금 ON ... WHERE 사람.조건 = 조건 AND 계약.날짜 between '202201' and '202205' GROUPBY 계약날짜 -- 월별문제는 건수가 너무 많다는건데요.. 해당 데이터는 전체 몇백만건으로,[계약] - [입금내역]간 조인에 많은 시간이 소요되고 있어요..해당부분을 해소하기위한 방법으로는 어떤게있을까요? 아래 방법이 가능할까요?1. 서비스단에서 월별로 쿼리를 나누어서 실행 for문을 통해 총 5회의 쿼리를 수행...2. 쿼리자체에서 5번으로 수행해서 결과도출 (UNION ALL)영한님이였으면 어떻게 성능을 개선했을지 궁금합니다..
- 미해결실전! Querydsl
이상황에는 nativequery가 최선일까요..?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]QueryDsl로 [계약]테이블에서 [시작날짜], [종료날짜]를 조회해옵니다.그리고 API응답으로 기간(시작날짜~종료날짜)을 추가해주어야 하는데요.이것을 처음에는 Query로 두날짜를 디비에서 조회해오고, 서비스단에서 두날짜를 계산해서 일수를 응답해줬는데,비지니스 변경사항으로, 기간순으로 Orderby를 해야하는게 추가되었어요. Sorting조건이 총 4개인데 (그중하나가 기간)제가 생각해낸건... 우선 query에서 orderby를 해야겠다. 싶어서 select절에서 해당 기간을 계산하기로 했어요.PostgreSQL사용중인데 date_part 함수로 계산 할 수 있더라구요. -> 근데 이게 jpql에 지원안하는건지 querydsl로는 풀수가 없어서...NativeQuery로 해결했구요. orderby도 4가지로 동적처리를 해줘야해서 문자열로 컨트롤해서 처리했습니다.. ("... order by " + orderParam ;")영한님이면 어떻게 처리했을지... 너무나궁금해서 글남겨봅니다..
- 미해결실전! Querydsl
where절 BooleanBuilder 를 통한 null처리
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. where절을 이용한 동적쿼리를 작성할때 아래와 같이 조합하는 경우 ageGoe(ageGoe)가 null을 반환하면 NPE가 발생하기때문에 null체크를 해줘야 한다고 배웠습니다. private BooleanExpression ageBetween(int ageLoe, int ageGoe) { return ageGoe(ageGoe).and(ageLoe(ageLoe)); } 이에대한 해결책으로 eq같은 경우 파라미터가 null인 경우 IllegalArgumentException 예외를 던지기 때문에 이를 이용하여 아래와 같이 코드를 작성하면 null이 아닌 빈 BooleanBuilder를 반환하여 BooleanBuilder를 조합하는 방식으로 해결된다는 사실도 확인했습니다. 하지만 내부적으로 eq("") 이런 경우에 대한 처리는 되어있지 않고 실제로 ""를 넘겼을때 쿼리에서 member0_.username="" 이런식으로 동작하는걸 확인했습니다. 1. eq에서 ""로 들어올때 처리를 어떤식으로 해줘야 할까요? 그리고 member.age.goe(ageGoe) 의 경우 ageGoe에 null이 들어오는 경우 내부적으로 private ConstantImpl(T constant) { this((Class) constant.getClass(), constant); } 2. 이 메서드에서 constant.getClass() 부분에서 NPE가 발생합니다. 때문에 nullSafeBuilder 에서 NPE에 대해 catch로 처리를 하면 되긴 하지만 이 방법이 맞는지 모르겠습니다. 위 1, 2 질문에 대해 nullSafeBuilder를 쓰지 않고 각 메서드에서 if절로 처리하면 정상적으로 동작하고 해결이 되지만 nullSafeBuilder로 해결하려면 어떤식으로 작성해야할까요? private BooleanBuilder usernameEq(String usernameCond) { /*if (hasText(usernameCond)) { return new BooleanBuilder().and(member.username.eq(usernameCond)); } else { return new BooleanBuilder(); }*/ return nullSafeBuilder(() -> member.username.eq(usernameCond)); } private BooleanBuilder teamNameEq(String teamNameCond) { return nullSafeBuilder(() -> team.name.eq(teamNameCond)); } private BooleanBuilder ageGoe(Integer ageGoeCond) { /*if (ageGoeCond != null) { return new BooleanBuilder().and(member.age.goe(ageGoeCond)); } else { return new BooleanBuilder(); }*/ return nullSafeBuilder(() -> member.age.goe(ageGoeCond)); } private BooleanBuilder ageLoe(Integer ageLoeCond) { return nullSafeBuilder(() -> member.age.loe(ageLoeCond)); } public static BooleanBuilder nullSafeBuilder(Supplier<BooleanExpression> f) { try { return new BooleanBuilder(f.get()); } catch (IllegalArgumentException e) { return new BooleanBuilder(); } catch (NullPointerException e) { return new BooleanBuilder(); } }
- 미해결실전! Querydsl
소수점 반올림을 어떻게 설정해야 하나요?
queryFactory.select(new QReviewHospitalDto(evCriteria.averageRate.avg(), reviewHospital.count())).from(reviewHospital).avg() 함수를 사용하는데. 3.33333333 이런식으로 계속 계산되는데, 소수점 2번째 자리까지만 나타내고 싶으면 어떻게 표현해야하는지 궁금합니다. averageRate.avg()에서 무엇을 더 추가해야 되나요?
- 미해결실전! Querydsl
querydsl Repository class를 만들고 @Repository 써서 사용하면 ....
querydsl Repository class를 만들고 @Repository 써서 사용하면 web에선 동작이 되는데 Junit5 Test Code에 @Autowired로 주입하면 동작이 안되네요. 혹시 이유를 알수 있을까요? 그럼 곡 Repository class를 impl class로 두고 그걸 상속하는 Repository interface를 사용하는 방식이 OOP 관점에선 맞는 방식인 것 같긴한데 아예 동작이 안되는 이유는 모르겠네요. JUnit5 TestCode에서
- 해결됨실전! Querydsl
intellij 단축키 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요 유사한 질문있는지 검색해보고 싶은데 뭐라 검색해야 될지 몰라서... 바로 질문드립니다 windows intellij 로 ctrl + alt + v 사용 많이 하시던데 알려주셔서 저도 잘 쓰고 있습니다 감사합니다 그런데 querydsl을 배우는 중에는 queryFactory .selectFrom(member) .where(member.username.eq("member1") .and(member.age.eq(10))) .fetchOne(); 이렇게 예쁘게 엔터 넣어서 쓰고 ctrl + alt + v 를 누르면 Member findMember = queryFactory.selectFrom(member).where(member.username.eq("member1").and(member.age.eq(10))).fetchOne(); 이렇게 한 줄로 바뀝니다 강의 영상에서는 엔터가 그대로 들어가고 Member findMember = queryFactory .selectFrom(member) .where(member.username.eq("member1") .and(member.age.eq(10))) .fetchOne(); 이렇게 예쁜 형태를 유지하는 걸로 보이네요 어떤 설정을 바꾸면 되는 알 수 있을까요 항상 감사합니다
- 미해결실전! Querydsl
Sort관련 질문있습니다!.
안녕하세요 ! 스스로 이해를 잘못하고있는거 같아서 이전 강의들 포함 다시 돌려보아도 이해가 되질 않아 질문드립니다. pageable을 클라이언트가 order조건까지 요청하였을때 그 pageable의 sort()를 querydsl의 orderby로 변환하는 과정에서 OrderSpecifier를 사용한다고 이해하였습니다. 근데 적어주신 내용에 "루트 엔티티 범위를 넘어가는 동적 정렬 기능이 필요하면 스프링 데이터 페이징이 제공하는 Sort 사용하기 보다는 파라미터를 받아서 직접 처리하는 것을 권장한다." 라는 의미가 예를들어 Member의 team의 name으로 sort를 하는데 클라이언트가 teamNameOrder=True 같은 값을 요청하고 그요청 파라미터를 기준으로 동적으로 querydsl쿼리 order를 처리하라는 말씀이신가요? 머리가 안좋아서 헷갈리네요 ㅜ_ㅜ
- 미해결실전! Querydsl
BooleanBuilder, BooleanExpression 차이
영한님 안녕하세요 작년 7월부터 스프링 공부했는데 어느새 여기까지 왔네요,, 좋은 강의 덕분에 재밌게 잘 공부하고 있습니다 . BooleanBuilder와 BooleanExpression 차이를 알고 싶어서 다이어그램을 보았습니다. Expression을 상속하고 있는 클래스더라구요 그래서 "도대체 무슨 차이지"라고 생각이 들어 찾아보았습니다. 동욱님 블로그 를 참고하고나서 제 생각엔 BooleanBuilder는 where 조건에 BooleanBuilder 객체 자체를 넣으니 코드를 이해하는데 가독성이 떨어진다고 생각했습니다.(조건들이 하나의 BooleanBuilder에 있기 때문) . BooleanExpression을 사용하면 여러 조건들을 각각 BooleanExpression을 반환하는 메서드를 만들어 가독성 좋게 조건들을 나열할 수 있고, 조합을 할 수 있다라고 생각했습니다. . 하지만 옛날에 영한님이 Q&A에 대한 답을 보았을 때, BooleanBuilder로도 충분하게 가독성 좋은 코드를 만들 수 있더라구요 . 그래서 제 생각엔 두 가지의 차이점이 보였습니다 . 1. BooleanExpression은 null일 경우 그냥 null만 반환해도 되지만, BooleanBuilder는 항상 BooleanBuilder라는 객체를 생성하여 반환해야하기 때문에 리소스 측면에서 낭비이다? 2. BooleanExpression은 ","을 이용해서 where조건에 여러 BooleanExpression의 조건들을 나열할 수 있지만, BooleanBuilder는 where에 나열할 수 없다? 정도라고 생각이 드는데, 아직까지 뭐가 확실하게 다른거지라는 생각이 들어 질문드립니다! 감사합니다
- 미해결실전! Querydsl
inner조인 할 때 2번째 파라미터를 써주는 이유가 무엇인가요?
일반조인시 leftJoin(member.team, team) 이렇게 member.team과 team 두 개의 파라미터를 써주게 되는데요 이 부분이 JPQL의 member.team as team 구문에 대응된다면 두 번째 파라미터에는 "t" 같은 string 타입의 alias가 오든지 QueryDSL에서 Q객체를 만들어서 별칭을 관리한다면 leftJoin(member.team) 그냥 이렇게 member.team만 적어줘도 되지 않았을까 라는 의문이 들어서요. 혹시 기능적으로나 의미적으로 이유가 있는지 궁금해서 질문드립니다.
- 미해결실전! Querydsl
동적 쿼리 작성을 위한 SearchCondition 사용시 주의사항
안녕하세요. 강사님. 동적 쿼리 작성을 위해 SearchCondition 방식을 팁으로 알려주셨는데요. SearchCondition 과 엔티티의 필드가 1:1 로 이루어져야 동적 쿼리 작성에 유용할거 같은데 SearchCondition -> BooleanBuilder 로 변환해야되고 이 과정에서 메모리 사용량이 많아질거 같은데요. SearchCondition 적용하므로 인한 메모리 이슈등은 없었는지요? 해당 이슈를 방지할수 있는 팁이 좀 더 있을까요?^^
- 미해결실전! Querydsl
스칼라 서브쿼리 작성시 limit 관련
안녕하세요. Querydsl 이용한 select절 서브쿼리 사용시 질의사항 있어 글남깁니다. 스칼라 서브쿼리 작성 중에 limit를 걸어 하나만 출력해야 하는 로직이 있는데, 실제 쿼리 나가는것을 보니 limit가 적용이 안되더라구요. 혹시 이런 경우에 어떤 방식으로 처리하셨는지 궁금합니다 !
- 해결됨실전! Querydsl
Querydsl4RepositorySupport.applyPagination의 countQuery질문
안녕하세요. 질문에 앞서 좋은 강의 감사합니다. Querydsl4RepositorySupport클래스의 applyPagination메소드에서 fetchCount()를 하여 리턴해주시는데 강사님도 아시다시피 fetchCount가 deprecated되어서 앞에서 실습했던 MemberRepositoryImpl.searchPageComplex 처럼 바꾸고 싶은데(fetchOne사용) 어떻게 해야 할지 막막하네요. 제 생각에는 countQuery부분이 JPAQuery<Long>을 반환해줘야 하는데 이를 위해서는 (어디선가 들어만 본...)수퍼타입토큰을 사용해야 할 것 같습니다. 그런데 이걸 이용해서 문제를 풀려고해도 잘 안풀리네요 혹시 강사님은 이 문제를 어떤식으로 해결하셨는지 궁금합니다.
- 해결됨실전! Querydsl
삭제 벌크 연산 flush() 호출
영한님 안녕하세요. 벌크 연산 후, flush(), clear() 처리를 해줘야 DB와 영속성 컨텍스트 에 있는 엔티티 상태가 같게 유지 된다고 하셨는데요. 삭제 벌크 연산 같은 경우에는 flush(), clear() 처리를 별도로 해주지 않더라도 데이터 조회해보면 삭제되어서 조회가 안되더라구요.. 그렇게 되면 삭제 연산 시에는 굳이 flush, clear 처리를 안해줘도 되는게 아닌가요?? 강의 삭제 테스트 코드에서도 확인해보니 flush 호출을 안했는데도 조회 시 데이터가 삭제되어 있습니다. ㅠㅠ @Test public void bulkDelete() { List<Member> result = queryFactory .selectFrom(member) .fetch(); // 104명 for (Member member1 : result) { System.out.println("member1 = " + member1); } long count = queryFactory .delete(member) .where(member.age.gt(18)) .execute(); System.out.println("delete count="+count); // 84 List<Member> result1 = queryFactory .selectFrom(member) .fetch(); // 20명 for (Member member1 : result1) { System.out.println("member1 = " + member1); } }
- 해결됨실전! Querydsl
offset과 distinct
팀과 멤버 (1:N) 팀 A의 멤버1, 멤버2, 멤버3, 멤버4, 멤버5가 있습니다. 팀A를 멤버와 함께 fetchjoin해서 가져오게 되면 팀A 객체 5개가 반환됩니다. 그런데 querydsl에서 아래와 같이 distinct()를 사용하지 않고 offset()만 사용하였는데 queryFactory .selectFrom(team) .join(team.members, member).fetchJoin() .offset(pageable.getOffset()) .fetch(); distinct 한 것처럼 중복이 제거되었습니다. 무슨 이유일까요?
- 미해결실전! Querydsl
List 형태의 검색조건에 대해
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요! 프로젝트 하다 궁금한 부분이 있는데 검색조건이 굉장히 많은 검색을 구현하게 되었어요. 조건이 PositionType positionType,List<String> majorSkillKeywords,String minorSkill,List<HopeWorkState> hopeWorkStates,List<PositionWorkManShip> positionWorkManShips 대강 이러한 파라미터들로 이루어지는데 단일 파라미터가 아닌 List 형태의 파라미터는 BooleanExpression을 활용한 메서드를 어떻게 구성해줘야 하는지 감이 잘 안잡혀요. BooleanExpression을 리스트 형태로 반환하는 형태의 메서드로 구성하면 되려나요? 예를들어 majorSkills 에 대해선 private List<BooleanExpression> eqMajorSkills(List<String> majorSkillKeywords) 이런 형태의 메서드로요. 맞는 방식인지도 모르겠네요ㅜㅜㅜ
- 해결됨실전! Querydsl
QMemberTeamDto의 NoClassDefFound
안녕하세요 강의 잘 듣고 있습니다. 중간에 조회 API 개발의 내용 중 QMemberTeamDto를 조회하는 메소드로 컨트롤러를 통해 응답을 주는 컨트롤러를 작성하는 내용이 있는데요 같은 내용의 Test는 통과하였으나 포스트맨에서 요청을 할 때는 NoClassDefFound 에러가 발생합니다 build가 되지 않았나? 해서 gradle로 clean compileJava compileQuerydsl 모두 실행하고 해봐도 같은 결과입니다 빌드된 결과 에러 내용
- 해결됨실전! Querydsl
DTO 클래스의 위치? 관련해서 질문 드립니다!
안녕하세요. 강의 너무나 잘 듣고 있어 언제나 감사드립니다. (_ _) DTO 관련해서 궁금점이 있어 질문드립니다. 제가 많이 본, 그리고 제가 지금도 쓰고있는 폴더 트리(패키지 구조)가 아래와 같이 사용하고 있습니다. - Model - | Repository - | Service - | Controller ▼ Service단의 경우에는 다른 서비스단에서 연계해서 사용될 수도 있다고 들은적이 있어서, 최대한 Model 클래스를 반환되도록 사용하고 있구요. 위와 연계해서 Controller단에서 Model 클래스를 DTO로 변환해서 반환을 했습니다. 그래서 DTO의 위치가 Controller 패키지에 위치시키고 있었습니다. 그런데 join 쿼리로 인해서 DTO를 Repository에서 반환하게 된다면, 해당 DTO의 위치가 맨 끝인 Controller 패키지에 있어도 되는 걸까요?
- 미해결실전! Querydsl
fetchJoin() 외에 Team 엔티티 가져오기
안녕하세요 강사님, 항상 좋은 강의 잘 듣고 있습니다! 강의에서 fetchJoin()을 했을때와 하지 않았을때의 차이는 앞서 수강했던 JPA 강의에서 학습을 했기 때문에 이해 했습니다. 강의를 수강하던 중, fetchJoin()을 사용하지 않고도 Team 엔티티를 가져올 수 있는 방법이 있을까 고민해본 결과, 아래의 코드가 나왔습니다. em.flush();em.clear(); Tuple findMemberJoinB = factory .select(member, team).from(member).join(member.team, team).fetchFirst();Team findTeamB = findMemberJoinB.get(1, Team.class);System.out.println("findTeamB = " + findTeamB); 실행 결과, Team 엔티티도 의도한대로 가져오고, 쿼리문도 fetchJoin을 사용 했을때와 동일하게 하나의 쿼리문만 처리되는 것을 확인 했습니다. ( select ...(생략)... from member member0_ inner join team team1_ on member0_.team_id=team1_.team_id limit 1; ) 이렇게 연관된 엔티티를 가져오는 것이 fetchJoin을 사용했을때와의 동일한 결과인 것이 맞나요? 혹시 이렇게 할 경우 생길 수 있는 오류가 있을까요? 답변 감사드립니다!