30%
61,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! Querydsl
jpaqueryfactory 권장 이유를 알 수 있을까요?
안녕하세요. 강의 정말 잘 듣고 있습니다!! 강의를 보면서 jpaqueryfactory를 최근 버전에서 권장하신다고 하셨는데, 혹시 왜 권장되어지고 있는지 이유를 알 수 있을까요?
- 미해결실전! Querydsl
Full outer join 질문있습니다 !
Querydsl로 Full outer join이 가능할까요?
- 미해결실전! Querydsl
join 여러번 할 경우 질문있습니다.
여러 엔티티들과 조인하고 싶으면 .join().join() 이렇게 조인 뒤에다 조인 써서 하면 되나요?
- 미해결실전! Querydsl
select 절에서 필드와 집계함수 동시 나열 문제
강의 예문) List<Tuple> result = queryFactory .select(member.username, JPAExpressions .select(memberSub.age.avg()) .from(memberSub) ) .from(member) .fetch(); 안녕하세요. select(member.age.avg(), member.age.max()) from(member)은 가능한데 위 예문을 select(member.username, member.age.avg()) .from(member)으로 바꿀 수 없는 이유가 무엇일까요?쿼린이라 질문이 초보적인 점 부디 이해를 부탁드립니다.
- 미해결실전! Querydsl
콘솔의 결과 코드와 작성한 jpql 간 차이
강의 예제) 회원과 팀을 조인하면서 팀 이름이 teamA인 팀만 조인, 회원만 모두 조회 위 예제를 가지고 querydsl을 작성하기 전에 먼저 선생님이 JPQL로 작성해주신 구문은 다음과 같은데요. JPQL: select m, t from Member m left join m.team t on t.name = 'teamA'; 테스트 결과 화면 설명해주실 때 콘솔 주석의 jpql은 with가 들어있더라구요. 이 둘이 다른 이유가 있을 것 같은데 무엇 때문일까요? /* select member1, team from Member member1 left join member1.team as team with team.name = ?1 */
- 미해결실전! Querydsl
예문 쿼리 결과 정렬 순서와 containsExactly
안녕하세요! 선생님의 보배로운 강의 넘나 잘 듣고 있습니다. 강의 중에 containsExactly("teamA", "teamB")에 관해 질문이 있는데요. 찾아보니 값만 맞으면 되는 게 아니라 순서도 맞는지 확인하는 것 같은데, 이때 "teamA", "teamB"가 맞으려면 오름차순 정렬이 되어야 하잖아요? 하지만 select ftom where문의 결과는 기본적으로 어떻게 정렬될지 알 수 없는 것 아닌지요?
- 미해결실전! Querydsl
querydsl와 jdbctemplate 의 성능 비교 질문입니다.
안녕하세요 김영한님, querydsl 강의를 수강중인 학생입니다. 수강중에 문득 querydsl 은 동적으로 query 를 만들어주는 도구이다 보니 jdbctemplate 와 querydsl 간의 성능에 따른 차이가 있을것으로 생각되어 검색을 해보았습니다. 아래의 stackover flow 에 기재된 내용으로는 약 6배 정도 차이가 난다고 적혀있는데요 실무에서 이정도의 성능적인 차이가 발생하는지 궁금합니다. https://stackoverflow.com/questions/38123217/performance-tests-between-querydsl-sql-vs-jdbctemplate 만약에 이렇게 성능적으로 차이가 많이 발생하게 된다면 실제 service 단계에서도 서버의 메모리나 확장에 관해서도 많은 리소스가 추가로 투입이 되어야할것 같습니다. 최근들어 쿠버네티스를 통해서 이러한 성능적이슈를 효율적으로 관리한다고 귓동냥으로 듣기는 했습니다. 저의 생각으로는 휴먼리소스를 투입해서 jdbctemplate 으로 코딩 할것인가 아니면 자본을 투입하여 문제를 해결할것인가의 문제로 보여 어떤것에 가치를 두냐에따라 답이 다른것같습니다. 이러한 jpa, jdbctemplate 의 성능적인 관점에서 김영한님 생각이 궁금합니다. 약간은 수업의 방향에 어긋나는것 같은 질문이라 조심스럽습니다... (ps. jpa 와 querydsl 의 성능을 비교하게 비슷할까요..? )
- 미해결실전! Querydsl
Spring Sort를 QueryDSL 변환 적용하는 방법 문의
안녕하세요. 강사님 QueryDSL 재미있게 배웠습니다. 정렬기준을 아래와 같이 받았을 때 pageable 파라미터를 이용해서 QueryDSL에 적용하는 방법에 대해서 고민입니다. 정렬기준 입력 형태: URI?sort=field1,asc&sort=field2,desc org.springframework.data.domain.Sort 방법1. pageable 값을 얻어와 직접 queryDSL에 OrderSpecifier로 지정 if (pageable != null) { query.offset(pageable.getOffset()); query.limit(pageable.getPageSize()); for (Sort.Order o : pageable.getSort()) { PathBuilder<Object> orderByExpression = new PathBuilder<Object>(Object.class, "object"); query.orderBy(new OrderSpecifier(o.isAscending() ? com.mysema.query.types.Order.ASC : com.mysema.query.types.Order.DESC, orderByExpression.get(o.getProperty()))); } } 방법2. applyPagination() 함수로 매핑 getQuerydsl().applyPagination(pageable, jPQLQuery); 결과적으로 방법2가 더 깔끔해 보이는데 원본 엔티티와 DTO객체가 달라서 org.hibernate.hql.internal.ast.QuerySyntaxException이 발생하는 이슈가 있습니다. 현재까지 결론은 방법1을 사용해야할 것으로 보이는데 더 좋은 방법을 아시는지 문의드립니다. 감사합니다.
- 미해결실전! Querydsl
where( , ) 사용시 OR 조건을 사용하는 방법
안녕하세요. return jpaQueryFactory .select(member) .from(member) .where(usernameEq(usernameParam), ageEq(ageParam)) .fetch() 위와 같이 where안에 콤마(,) 를 사용하면 and 조건으로 연결이 되는데요. 혹시 별도의 함수(OR조건으로 묶을수 있도록)를 만들지 않고 간단하게(콤마를 사용하는것 처럼) or 조건으로 연결하는 방법도 있을까요?
- 해결됨실전! Querydsl
Dto로 조회 관련 질문드립니다!
안녕하세요 팀장님 강의 내용을 토대로 다양하게 혼자 연습해보고 있는데, Dto로 조회하는 과정에서 오류가 계속 발생했는데 어떤식으로 해결해야될지 몰라서 질문 남깁니다.! Member - Team 관계에서 Team을 Dto로 조회하는 과정입니다. 우선 Dto말고 Tuple로 조회했을때는 정상 동작했습니다. 1. Tuple 조회 ( 정상 동작) @BeforeEachpublic void setup() { queryFactory = new JPAQueryFactory(em); Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); em.persist(teamA); em.persist(teamB); Member member1 = new Member("member4", 10, teamA); Member member2 = new Member("member4", 20, teamA); Member member3 = new Member("member4", 30, teamB); Member member4 = new Member("member4", 40, teamB); Member member5 = new Member("member5", 40, teamB); em.persist(member1); em.persist(member2); em.persist(member3); em.persist(member4); em.persist(member5); em.flush(); em.clear();} List<Team> fetch = queryFactory .selectFrom(team) .join(team.members, member).fetchJoin() .fetch();System.out.println("fetch.get(0).getMembers() = " + fetch.get(0).getMembers()); 정상동작 2. Dto 조회 @Datapublic class TeamDto { private String name; private List<MemberDto> members = new ArrayList<>();} @Datapublic class MemberDto { private String username;} List<TeamDto> result = queryFactory .select(Projections.fields(TeamDto.class, team.name.as("name"), Projections.fields(MemberDto.class, member.username ).as("members") ) ) .from(team) .join(team.members, member).fetchJoin() .fetch();System.out.println("dto = " + result.get(0).getMembers()); 실행결과 not compatible with java.util.List이 발생했습니다. ㅠㅠ 이것저것 바꿔가면서 다양하게 시도해봤는데도 계속 오류가 발생했습니다.. 어떤 식으로 변경해야 될까요? 추가로 시도하면서 느낀게 한 개 이상의 Dto가 있을 경우 코드의 가독성이 너무 떨어지게 되더라고요. 혹시 팀장님께서는 여러개의 Dto를 조회할 때 따로 사용하는 방식이 있으신가요?
- 해결됨실전! Querydsl
(해당 영상직접 연관x) 강의 전반 package 구성 질문
삭제된 글입니다
- 미해결실전! Querydsl
Left join 에서 on절에 BooleanExpress 적용 가능할까요?
안녕하세요. QueryDsl에서 left join에서 동적으로 on절을 만들 수 있나요? .selectFrom(lesson).leftJoin(lesson.enrollmentLessons, enrollmentLesson).on(eqTutee(condition)) 위와 같이 사용 시 잘 동작중인데 eqTutee가 null 인 경우 에러가 발생합니다. 물론 동적으로 if를 사용해서 분기를 할 수 있긴 한데 좀 더 쉽게 할 수 있는 방법이 있을까 해서 문의드립니다.
- 해결됨실전! Querydsl
Querydsl 적용시 service와 seeviceImpl
안녕하세요 mybatis환경에서 변경해보고자 배우고 있는 중입니다. 다름이 아니라 예시에서 보여주신 소스를 보면 service나 serviceimpl없이 바로 controller에서 repo를 호출하는 형식으로 되어있는데, 실무에서도 이와 같이 사용하는지 아니면 controller service serviceimpl repo repoimpl 형식으로 쓰는지 궁금합니다. 이른 시간에 질문 올려 죄송합니다
- 해결됨실전! Querydsl
JPAQueryFactory 의존성 질문드립니다..!
안녕하세요~ 강사님~수업시간에 JPAQueryFactory를 @Bean으로 등록하셨는데 이걸 주입받은 객체에서 다른 객체로 넣어줘도 멀티쓰레드 환경에서 문제가 없을까요?? 샘플 코드 public interface FruitBehavior { List<FruitList> getFruitList();} @RequiredArgsConstructorpublic class BananaRepository implements FruitBehavior { private final JPAQueryFactory queryFactory; @Override public List<FruitList> getFruitList() { queryFactory .selectFrom(fruit); }} @RequiredArgsConstructorpublic class TestRepositorySupport { private final JPAQueryFactory queryFactory; private final Map<String, FruitBehavior> map = new HashMap<>(); void doSomething() { map.put("Banana", new BananaRepository(queryFactory)); // 여기!!! }} 대충 이런식으로 ...TestRePositorySupport에서 주입받은 queryFactory를 BananaRepository를 만들때 넣어줘도 문제가 없을까요?실행해봤는데 결과는 잘 출력되는데.. 혹시나 싱글턴이 깨지거나 다른 이슈들이 생기진 않을까 궁금합니다..!!
- 해결됨실전! Querydsl
테스트 오류 질문드립니다!!
안녕하세요 강사님~ RepositoryCustom - RepositoryCustomImpl 구현하고 Repository에서 RepositoryCustom상속하는 커스텀 있잖아요~ 여기서 기존에 @SpringBootTest로 실행되는 통합테스트를 @DataJpaTest로 변경하니까 변경한 모든 테스트가 깨지더라고요.. 빈을 생성하는 과정에서 오류가 나더라고요 ㅜㅜ `Error creating bean with name 'memberRepositoryCustomImpl' defined in files ~ ` `No qualifying bean of type 'com.querydsl.jpa.impl.JPAQueryFactory' available: expected at least 1 bean which qualifies as autowire candidate` 단위 테스트에서는 기본적으로 Repository는 @DataJpaTest로 실행하는 걸로 알고있는데, 이럴 경우 어떤식으로 해결을 해야되는 건가요?
- 해결됨실전! Querydsl
chmod 에러
chmod 755 h2.sh 명령을 실행하면 'chmod'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다 라고 나옵니다. 구글링해보니 windows10에서는 chmod 명령어가 지원되지 않는다는 것 같은데 어떻게 해야 할까요?
- 해결됨실전! Querydsl
쿼리 최적화 질문 (N+1문제)
안녕하세요! 강의 복습을 위해서 토이 프로젝트를 하는 중에 N+1 문제를 어떻게 해결해야 할 지 모르겠어서 질문 드립니다. 먼저, 제가 원하는 출력 결과는 아래와 같습니다. ====== 메뉴 정보 ====== id = 101 메뉴 = 후라이드 가격 = 14000 수량 = 2 ====== 옵션 정보 ====== 옵션 = 눈꽃 치즈볼 4개 가격 = 3500 수량 = 2 옵션 = 치즈볼 4개 가격 = 3000 수량 = 2 ====== 메뉴 정보 ====== id = 22 메뉴 = 후라이드 가격 = 14000 수량 = 1 ====== 옵션 정보 ====== 1. 엔티티 [그림 1]. 엔티티 설계 ※ OrderMenu에서 옵션을 선택하지 않으면 OrderMenu, OrderOption 조인 한 뒤에 OrderOption 조회 시 NullPointerException 발생해서 OrderMenu에 양방향 연관관계 추가 [그림 2]. Join 시 <null> 발생 2. 데이터 [그림 3]. 입력한 데이터 아래와 같은 테스트를 작성했을 때 [그림 4]과 같은 N+1 문제가 발생했습니다. @Testpublic void 주문메뉴_주문옵션조회() throws Exception { Long orderId = 100L; List<OrderMenu> fetch1 = queryFactory .select(orderMenu) .from(orderMenu) .where(orderMenu.order.id.eq(orderId)) .fetch(); for (OrderMenu orderMenu : fetch1) { System.out.println("====== 메뉴 정보 ======"); System.out.println("id = " + orderMenu.getId()); System.out.println("메뉴 = " + orderMenu.getMenu().getName()); System.out.println("가격 = " + orderMenu.getMenu().getPrice()); System.out.println("수량 = " + orderMenu.getQuantity()); List<OrderOption> orderOptionList = orderMenu.getOrderOption(); System.out.println("====== 옵션 정보 ======"); for (OrderOption orderOption : orderOptionList) { System.out.println(" 옵션 = " + orderOption.getOption().getName()); System.out.println(" 가격 = " + orderOption.getOption().getPrice()); System.out.println(" 수량 = " + orderOption.getQuantity()); } }} [그림 4] N + 1 문제 발생 위 문제를 해결하기 위해서 fetch join을 사용해서 OrderMenu와 OrderOption을 한 번에 불러왔지만 OrderMenu의 Menu, OrderOption의 Option은 여전히 Lazy loading이 되었습니다. @Testpublic void 주문메뉴_주문옵션조회() throws Exception { Long orderId = 100L; List<OrderMenu> fetch = queryFactory .selectFrom(orderMenu) .distinct() .leftJoin(orderMenu.orderOption, orderOption).fetchJoin() .where(orderMenu.order.id.eq(orderId)) .fetch(); for (OrderMenu orderMenu : fetch) { System.out.println("====== 메뉴 정보 ======"); System.out.println("id = " + orderMenu.getId()); System.out.println("메뉴 = " + orderMenu.getMenu().getName()); System.out.println("가격 = " + orderMenu.getMenu().getPrice()); System.out.println("수량 = " + orderMenu.getQuantity()); List<OrderOption> orderOptionList = orderMenu.getOrderOption(); System.out.println("====== 옵션 정보 ======"); for (OrderOption orderOption : orderOptionList) { System.out.println(" 옵션 = " + orderOption.getOption().getName()); System.out.println(" 가격 = " + orderOption.getOption().getPrice()); System.out.println(" 수량 = " + orderOption.getQuantity()); } }} 출력 내용 select distinct ordermenu0_.order_menu_id as order_me1_7_0_, orderoptio1_.order_option_id as order_op1_8_1_, ordermenu0_.menu_id as menu_id3_7_0_, ordermenu0_.order_id as order_id4_7_0_, ordermenu0_.quantity as quantity2_7_0_, orderoptio1_.option_id as option_i3_8_1_, orderoptio1_.order_menu_id as order_me4_8_1_, orderoptio1_.quantity as quantity2_8_1_, orderoptio1_.order_menu_id as order_me4_8_0__, orderoptio1_.order_option_id as order_op1_8_0__ from order_menu ordermenu0_ left outer join order_option orderoptio1_ on ordermenu0_.order_menu_id=orderoptio1_.order_menu_id where ordermenu0_.order_id=? ====== 메뉴 정보 ====== id = 101 2021-01-27 15:12:12.595 DEBUG 35340 --- [ main] org.hibernate.SQL : select menu0_.menu_id as menu_id1_3_0_, menu0_.created_date as created_2_3_0_, menu0_.last_modified_date as last_mod3_3_0_, menu0_.menu_category_id as menu_cat8_3_0_, menu0_.name as name4_3_0_, menu0_.price as price5_3_0_, menu0_.image_url as image_ur6_3_0_, menu0_.share_url as share_ur7_3_0_, menucatego1_.menu_category_id as menu_cat1_4_1_, menucatego1_.name as name2_4_1_, menucatego1_.restaurant_id as restaura3_4_1_ from menu menu0_ left outer join menu_category menucatego1_ on menu0_.menu_category_id=menucatego1_.menu_category_id where menu0_.menu_id=? 메뉴 = 후라이드 가격 = 14000 수량 = 2 ====== 옵션 정보 ====== 2021-01-27 15:12:12.604 DEBUG 35340 --- [ main] org.hibernate.SQL : select option0_.option_id as option_i1_6_0_, option0_.name as name2_6_0_, option0_.option_category_id as option_c4_6_0_, option0_.price as price3_6_0_ from options option0_ where option0_.option_id=? 옵션 = 눈꽃 치즈볼 4개 가격 = 3500 수량 = 2 2021-01-27 15:12:12.609 DEBUG 35340 --- [ main] org.hibernate.SQL : select option0_.option_id as option_i1_6_0_, option0_.name as name2_6_0_, option0_.option_category_id as option_c4_6_0_, option0_.price as price3_6_0_ from options option0_ where option0_.option_id=? 옵션 = 치즈볼 4개 가격 = 3000 수량 = 2 ====== 메뉴 정보 ====== id = 22 메뉴 = 후라이드 가격 = 14000 수량 = 1 ====== 옵션 정보 ====== OrderMenu와 OrderOption을 조회할 때, 연관된 Menu와 Option을 한 번에 조회하는 방법이 있을까요? 아니면 엔티티 설계를 변경해야 할까요?
- 미해결실전! Querydsl
Slice 질문 있습니다.
안녕하세요, 만약 Page대신 Slice를 사용하려고 하면 리미트에 +1 만큼하고 쿼리를 날리고, 다음페이지가 있는지 확인해야하는데, 이 부분은 아래 코드처럼 개발하는 사람이 직접 처리해주어야 하는건가요? List<MemberTeamDto> content = queryFactory .select(new QMemberTeamDto( member.id.as("memberId"), member.username, member.age, team.id.as("teamId"), team.name.as("teamName"))) .from(member) .leftJoin(member.team, team) .where( usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageBetween(condition.getAgeLoe(), condition.getAgeGoe())) .offset(pageable.getOffset()) .limit(pageable.getPageSize() + 1) .fetch();if (content.size() == pageable.getPageSize() + 1) { SliceImpl slice = new SliceImpl<>(content.subList(0, pageable.getPageSize()), pageable, true);} else { SliceImpl slice = new SliceImpl<>(content, pageable, false);} 그리고, 카운트 쿼리를 따로 날리는 Complex인 경우현재 Member와 Team이 다대일 이니깐 아래처럼leftJoin(member.team, team) 이부분 지워도 count는 똑같이 나오는게 맞죠?? queryFactory .selectFrom(member) .where( username(condition.getUsername()), teamName(condition.getTeamName()), ageBetween(condition.getAgeLoe(), condition.getAgeGoe()));
- 미해결실전! Querydsl
동적쿼리 BooleanBuilder 질문
안녕하세요 강사님, 강의 잘 보고 있습니다. 해당 강의 다른영상에서의 질문에서 BooleanBuilder와 자바 8을 이용해서 체이닝이 가능한 코드를 봣었습니다. 영상강의처럼 BooleanExpression을 사용한 ageBetween은 null이 반환될 수 있어서 테스트시 age를 안 넣으면 NPE가 뜨더라구요. 그래서 아래처럼 BooleanBuilder 사용한 코드로 바꾸면 null에 무조건 안전하게 되는게 맞는건가요? public List<MemberTeamDto> search(MemberSearchCondition condition) { return queryFactory .select(new QMemberTeamDto( member.id.as("memberId"), member.username, member.age, team.id.as("teamId"), team.name.as("teamName"))) .from(member) .leftJoin(member.team, team) .where( usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageBetween(condition.getAgeLoe(), condition.getAgeGoe())) .fetch();}private BooleanBuilder usernameEq(String username) { return nullSafeBuilder(() -> member.username.eq(username));}private BooleanBuilder teamNameEq(String teamName) { return nullSafeBuilder(() -> team.name.eq(teamName));}private BooleanBuilder ageGoe(Integer ageGoe) { return nullSafeBuilder(() -> member.age.goe(ageGoe));}private BooleanBuilder ageLoe(Integer ageLoe) { return nullSafeBuilder(() -> member.age.loe(ageLoe));}private BooleanBuilder nullSafeBuilder(Supplier<BooleanExpression> f) { try { return new BooleanBuilder(f.get()); } catch (Exception e) { return new BooleanBuilder(); }}private BooleanBuilder ageBetween(Integer ageLoe, Integer ageGoe) { return ageLoe(ageLoe).and(ageGoe(ageGoe));} 익셉션마다 BooleanBuilder 객체를 새로 만드는데, 객체를 생성할 때 드는 비용은 null을 위해서는 크게 상관이 없는거죠? 그리고, ageBetween 부분에서 강의는 파라미터를 int 타입으로 받는데, 테스트시 NPE가 나와서 Integer로 바꾸니 되더라구요. 이유가 원래 Integer타입을 int로 자동 언박싱하는 중에 null을 int에 넣지 못해서 NPE가 뜨는건가요?
- 미해결실전! Querydsl
INSERT에 대한 부분을 개발하려고 합니다.
강의 내용을 훑어봤는데 INSERT에 대한 내용이 없는 것 같아 질문 남깁니다. INSERT의 경우에 RepositoryImpl클래스 내부에 만드는 것이 나은지 아니면 Spring JPA 를 통해서 서비스 클래스 내부에서 entity클래스를 만들어 save를 하는게 나은지 궁금합니다.