30%
61,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! Querydsl
AttributeConverter로 적용하는 필드에 대해 그룹함수 적용은 어떤 방식으로 해야할까요?
안녕하십니까 집합 함수 적용에 관해 궁금한 점이 있어서 질문 드립니다. 아래와 같이 AttributeConverter 적용 필드의 경우에는 QueryDSL로 집합함수 적용이 가능한 방법이 있는지 궁금합니다. public class Product { public enum ProductStatus { PROCEEDING, SOLD_OUT;} @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "PRODUCT_ID") private Long id; @Column(name = "TITLE") private String title; @Column(name = "PRICE") private Money price; } public class Money { public static final Money ZERO = Money.wons(0); private final BigDecimal amount; public static Money wons(long amount) { return new Money(BigDecimal.valueOf(amount)); } public static Money wons(double amount) { return new Money(BigDecimal.valueOf(amount)); } public static <T> Money sum(Collection<T> bags, Function<T, Money> monetary) { return bags.stream().map(bag -> monetary.apply(bag)).reduce(Money.ZERO, Money::plus); } Money(BigDecimal amount) { this.amount = amount; } public Money plus(Money amount) { return new Money(this.amount.add(amount.amount)); } public Money minus(Money amount) { return new Money(this.amount.subtract(amount.amount)); } public Money times(double percent) { return new Money(this.amount.multiply(BigDecimal.valueOf(percent))); } public Money divide(double divisor) { return new Money(amount.divide(BigDecimal.valueOf(divisor))); } public boolean isLessThan(Money other) { return amount.compareTo(other.amount) < 0; } public boolean isGreaterThan(Money other) { return amount.compareTo(other.amount) > 0; } public BigDecimal getAmount() { return amount; } public Long longValue() { return amount.longValue(); } public Double doubleValue() { return amount.doubleValue(); } public boolean equals(Object object) { if (this == object) { return true; } if (!(object instanceof Money)) { return false; } Money other = (Money)object; return Objects.equals(amount.doubleValue(), other.amount.doubleValue()); } public int hashCode() { return Objects.hashCode(amount); } public String toString() { return amount.toString() + "원"; } } @Converter(autoApply = true) public class MoneyConverter implements AttributeConverter<Money, Long> { @Override public Long convertToDatabaseColumn(Money money) { return money.getAmount().longValue(); } @Override public Money convertToEntityAttribute(Long amount) { return Money.wons(amount); } }
- 해결됨실전! Querydsl
Member에서 타고 들어가는 생성자에 관한 질문
@Entity@Getter @Setter@NoArgsConstructor(access = AccessLevel.PROTECTED)@ToString(of = {"id", "username", "age"})public class Member { @Id @GeneratedValue private Long id; private String username; private int age; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "TEAM_ID") private Team team; public Member(String username) { this(username, 0); } public Member(String username, int age) { this(username, age, null); } public Member(String username, int age, Team team) { this.username = username; this.age = age; if (team != null) { changeTeam(team); } } 에서 public Member(String username) { this(username, 0); } 을 보면, public Member(String username) { this(username, 0, null); } 이 아니라 public Member(String username) { this(username, 0); } 을 사용한 이유는 가독성 때문인가요 ?
- 해결됨실전! Querydsl
QHello qHello = new QHello(
좀 쓸데없는 곳에 꽂혀있는 거일 수도 있는데 new QHello("h")에서 "h"는 무슨 역할을 하나요 ? 조금 찾아보니까 static을 사용해서 QHello.hello하면 new QHello("Hello") 라고 하던데 문자로 엔티티를 찾는 용도였으면 강의에서 "h"로 넣기도 했으니까 아닌 것 같고.. intelliJ로 함수를 쫓아쫓아가보니까 한도 끝도 없어서.. 초보인 저에게는 잘 모르겠더라구요 new QHello("h")에서 "h"의 용도가 무엇일까요 ?
- 미해결실전! Querydsl
Impl 네이밍 규칙 질문
안녕하세요, 질문이 있어서 글을 남깁니다! MemberRepositoryImpl 이라는 클래스명에 정해진 규칙이 있는건 조금 알겠지만, 제 코드 상에서는 MemberRepositoryCustom의 구현체명, 즉 강의에는 MemberRepositoryImpl 로 되어있는 클래스를 MemberRepositoryCustomImpl로 변경해도 정상 동작하더라구요! 혹시 원인을 알 수 있을까요?? 감사합니다 :)
- 해결됨실전! Querydsl
내부조인 on 사용
안녕하세요 영한님 저는 jpa 야생형 로드맵을 수강한 후 토이프로젝트를 진행하고 있는 도중 여쭈어보고 싶은게 생겨서 글을 올리게 되었습니다. 먼저 해당 강의를 통하여 내부조인을 사용하면, where 절에서 필터링 하는 것과 기능이 동일하기 때문에 where절의 의도와 맞게 내부조인에서는 on절이 아닌 where절을 사용하는게 좋다고 이해하였습니다. 아래 사진은 파라미터가 Item의 name에 포함된 경우 해당 Item의 관련된 여러 테이블을 join하여 Shop을 조회하고 싶어서 작성하게 된 코드와 실행했을 때 나타난 쿼리입니다. 처음에는 findByNameContainsV1 메소드를 작성하였지만 Item부터 Shop 사이에 있는 모든 테이블을 조인한 후 where절에서 Item의 name과 같은 Shop을 조회하기 때문에 조금 더 쿼리를 최적화 시킬 수 있다고 생각했습니다. 그래서 findByNameContainsV2 메소드를 작성하게 되었는데요. sql 문법상 join이 where보다 먼저 실행된다고 알고 있었기 때문에 where 대신 on절을 넣어주었습니다. 하지만 테스트를 통하여 on절에도 동적쿼리를 사용할 수 있는지 확인해 보았지만 불가능했습니다. 아직 개발에 대한 지식이 많이 부족해서 성능 최적화에 대해 잘 모르지만 저는 findByNameContainsV2 메소드가 findByNameContainsV1메소드보다 더 성능이 잘 나온다고 생각이 되지만 QueryDSL은 JPA에서 동적 쿼리를 사용하기 위해 실무에서 도입하게 된 것이므로 굳이 고민하지 않아도 되는 것인지, 아니면 실무에서 동적쿼리가 아닌 경우에 findByNameContainsV2 메소드와 같이 코드를 작성해도 되는지 영한님의 의견을 여쭈어 보고 싶습니다.
- 미해결실전! Querydsl
StringPath to NumberPath
안녕하세요. 강의 재밌게 보고있습니다. db 설계를 잘못해서 student 테이블의 department_id는 varchar(11) department 테이블의 id는 int(11) 로 설계한 상태에서 queryDSL로 where 조건을 student.department_id = department.id 이렇게 주고싶은데 student.department_id = StringPath department.id = NumberPath 로 둘 형식이 달라서 비교가 안 됩니다. DB 설계를 바꾸지 못하는 상황에서 저 두개를 어떻게 비교할 수 있을까요?? StringPath에 보니까 castToNum이 있던데 이걸 사용하면 될까요??
- 미해결실전! Querydsl
leftjoin을 사용한 이유
public List<MemberTeamDto> search(MemberSearchCondition condition) { return queryFactory .select(new QMemberTeamDto( member.id, member.username, member.age, team.id, team.name )) .from(member) .leftJoin(member.team, team) .where( usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe()) ) .fetch(); } 이때 leftJoin(member.team, team)을 사용하신 특별한 이유가 있나요? join을 사용하면 안되는 건지 궁금합니다!
- 미해결실전! Querydsl
selectSubQuery()에서 결과값에 접근하는 방법!
Querydsl 강의를 듣던 도중, 16강(서브 쿼리)에서 마지막 코드에 대한 질문입니다. 저는 강의를 Kotlin으로 학습하고 있는데요, result의 타입이 `List<Tuple>` 이고, 이 리스트에 있는 각 `Tuple`들에 접근해서 age를 꺼내오고 싶습니다. `for (tuple in result)`로 하나의 `Tuple`을 순회하며 `println(tuple)`을 해보면, 강의 내용과 동일하게 나오지만, `println(tuple.get(member.age))` 또는 `println(tuple.get(member.age.avg()))`는 null 이라고 출력됩니다.. `println(tuple.get(member.username))`은 잘 나오는데, age만 null이라고 출력되어 이 age에 어떻게 접근할 수 있을지 궁금해서 질문 남깁니다!!
- 해결됨실전! Querydsl
@Autowired vs @PersistenceContext
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] MemberTest 코드에서 EntityManager를 @PersistenceContext 를 통해 주입받으셨는데 @Autowired 로 주입을 받아도 정상적으로 작동하더라고요. 찾아보니 @PersistenceContext 를 통해 EntityManagerFactory에서 주입받기 위해서다, 여러 요청에 대하여 동일한 EntityManager를 반환하기 위해서이다. 라는 말을 들었는데 위의 이유들 때문인가요? @Autowired vs @PersistenceContext 의 차이를 알고싶습니다.
- 미해결실전! Querydsl
QUERYDSL rank 함수 문의
안녕하세요 강사님 querydsl 에서 rank 함수 사용법 문의드립니다. 개인적으로 검색해본 결과는 SqlQueryFactory를 사용해서 SqlExpression을 쓰면 되던데.. 해당 내용으로 변경해서 querydsl 을 호출하니 엔티티 및 속성 맵핑이 제대로 안되더라구요 예를 들어 엔티티명이 Customer , 실제 테이블명 CUST 일 경우, Customer로 쿼리를 날려 테이블이 존재하지 않는다고 오류가 발생합니다. 어떻게 사용해야할까요? ㅠㅠ 답변 부탁드립니다. 감사합니다!
- 미해결실전! Querydsl
디폴트 정렬 조건 추가하고자 하는 경우
페이징 쿼리를 요청 받았을 때,디폴트로 제일 마지막에 날짜(끌올 기능도 넣고 싶어 orderAt이란 LocalDate 프로퍼티 추가)를 기준으로 디폴트를 넣고자 합니다 public Page<Post> getPagePostBySearch( List<District> districts, PostSearchCondition condition, Pageable pageable){ return applyPagination(pageableWithOrderAt(pageable), query -> query .selectFrom(post) .join(post.category, category).fetchJoin() .join(post.seller, account).fetchJoin() .join(post.district, district).fetchJoin() .where( defaultCond(districts), searchCond(condition) ));} private PageRequest pageableWithOrderAt(Pageable pageable) { List<Sort.Order> orders = pageable.getSort().get().collect(Collectors.toList()); orders.add(new Sort.Order(Sort.Direction.DESC, "orderAt")); return PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(orders));} 이때 이렇게 입력 받은 pagable로 부터 PageRequest를 새로 만들어 적용해 주었는데,pagable로 부터 모든 sort를 변환해서 가져온다음에 다시 적용하는것은 비효율적인 것 같아 다른 좋은 방법을 적용하고 싶은데, 잘떠오르지 않아 질문드립니다. 더 좋은 방법을 적용할수 있는 힌트를 얻을 수 있을까요? 답변주시면 감사드리겠습니다.
- 미해결실전! Querydsl
Querydsl 지원 클래스를 사용할때 sort 익셉션 처리관련 질문
QueryDsl 지원 클래스를 직접 사용할 경우, paging, sorting의 로직을 한곳에서 관리할 수 있는데 @GetMapping("/search")public ResponseEntity<ResponseOKDto<GetPagePostsResponseDto>> getPagePostsSearch( PostSearchCondition condition, Pageable pageable, @ApiIgnore HttpSession session){ Account account = accountService.checkSessionAndFindAccountWithActivityArea(session); Page<Post> pagePost = checkStatusParamAndFindPosts(account, condition, pageable); return new ResponseEntity<>(new ResponseOKDto<>(new GetPagePostsResponseDto(pagePost)), HttpStatus.OK);} 이런식으로 만들었을 경우, 프론트에서 해당 도메인 클래스에 없는 프로퍼티에 대해 잘못 sorting을 요청했을 때 익셉션 처리를 해주려고하는데요 querydsl 지원 클래스내에서 해당 익셉션을 처리할 경우, 아래와 같이 다른 도메인 controller에서도 따로 익셉션을 처리하지 않아도 된다는 장점을 가지는 것 같은데요 protected <T> Page<T> applyPagination(Pageable pageable, Function<JPAQueryFactory, JPQLQuery> contentQuery, Function<JPAQueryFactory, JPQLQuery> countQuery){ checkSortProperties(pageable); JPQLQuery jpaContentQuery = contentQuery.apply(queryFactory); JPQLQuery jpaCountQuery = countQuery.apply(queryFactory); List<T> content = getQuerydsl().applyPagination(pageable, jpaContentQuery).fetch(); return PageableExecutionUtils.getPage(content, pageable, jpaCountQuery::fetchCount);}private void checkSortProperties(Pageable pageable) { List<String> domainFields = Arrays.stream(domainClass.getDeclaredFields()).map(Field::getName).collect(toList()); List<String> sortFields = pageable.getSort().get().map(Sort.Order::getProperty).collect(toList()); if (!domainFields.containsAll(sortFields)) { throw new IllegalSortArgumentException("invalid sort property, properties must be in " + domainFields); }} 고민이 되는 점은 컨트롤러에서 미리 걸러줘야 할 것 같은데, 레포지토리내에서 익셉션 처리를 해줘도 되나?라는 의문이 들었습니다. 익셉션 처리 위치를 이렇게 해줘도 될까요? 아니면 번거롭더라도 각각의 도메인에 대해 일일히 컨트롤러 클래스 내에서 처리를 해줘야 할까요? 답변주시면 감사드리겠습니다.
- 미해결실전! Querydsl
쿼리 dsl, jpa 사용 케이스
간단한 쿼리도 Querydsl로 작성 시,미연에 에러를 방지할 수 있고, 생산성이 좋다는 강점을 가지고 있는데, 그렇다면 대부분을 쿼리 dsl로 작성하고 몇몇 케이스에서만 jpa로 작성하면 될까요?
- 미해결실전! Querydsl
페이징 방법 질문입니다!
안녕하세요, 항상 좋은 강의 감사합니다. offset기반의 페이지네이션의 성능이 데이터가 많을 수록 떨어지기 때문에 데이터가 적거나 간단하게 사용할 필요성이 있는 곳이 아니라면, cursor 기반 페이지네이션을 사용하는 것으로 공부했는데, 실무에서도 사용을 하는지 궁금합니다.
- 미해결실전! Querydsl
벌크 연산과 동기화 시점관련 질문
벌크 연산 수행 후 em.flush(), em.clear() 를 통해 동기화 해주셨는데 벌크 연산 작업 과 다른 비즈니스 로직의 타이밍이 일치하게 될 경우 (이 때 서로 같은 엔티티를 다루는 케이스가 있다고 가정) 비즈니스 로직에서 예를 들어 어떤 포인트를 100 올려주는 로직이 실행되고 (user a) + 어떤 (user b)는 포인트 100 감소 벌크 연산에서는 포인트가 3000이상인 경우 30% 증가라는 작업이 이루어 질때,(비즈니스 로직이 먼저 진행 사건이라고 가정, 근데 타이밍이 애매하게 걸치면)위의 비즈니스 로직이 적용되기 전에 포인트 벌크 작업이 진행될 수 도 있을 것 같습니다.(예시가 좀 좋지 않은것 같긴한데요)이런 케이스를 막기 위해서는 user a와 b의 결과가 적용될 수 있도록 em.flush(), em.clear()의 동기화 작업을 먼저하고 벌크 연산을 해줘야 하나? 라는 생각이 들었는데이런 케이스에서는 벌크 작업 후 동기화해도 문제가 없을까요?
- 미해결실전! Querydsl
빌드파일 안에 레포지토리
레포지토리를 왜 빌드파일에 생성하는 건가요?
- 미해결실전! Querydsl
질문있습니다
확실히 컴포넌트처럼 분리해서 사용하니 재사용성이 아주 좋다는것을 알았는데요. 그렇다면 실무에서 어떤 식으로 분리하는지 알고 싶습니다. 예전에 임플리먼트도 JpaEl 이런식으로 네이밍 규칙의 권장사항이 있는것처럼 해당 메소드만 쓰는 적당한 네이밍규칙이라던가,,(물론 실무 프로젝트에 따라 많이 다를 수 도 있겠지만요! 감이 잘 잡히지않아서 질문드리는거라서 ㅠㅠ) 여튼, 하나에 서비스(ex, MemberService)에 모든 Eq 를(name, age, 등등) 다 몰아넣기는 너무 많을 경우에는 어떻게 하시는지(지저분해보여서 생각보다..) 따로 클래스를 만들어서 분리시킨다면 어떤식의 네이밍 규칙을 사용하는지 알고 싶습니다. 질문이 너무 초급적이라 죄송합니당 ㅠㅠ
- 미해결실전! Querydsl
상속 구조에서 querydsl 조회하기
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://docs.google.com/document/d/1j0jcJ9EoXMGzwAA2H0b9TOvRtpwlxI5Dtn3sRtuXQas/edit#heading=h.w2tomwsznga7)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://docs.google.com/document/d/1xCQKit-1V6l6ObeCe49St33RHPzLF_P_c3o7aSDTKs0/edit#heading=h.7dhnp46ven0v)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]여기에 질문 내용을 남겨주세요. 이전 강의 에서 Entity에서 Iteam을 Book , Movie, Ablum으로 상속하는 구조를 가지고 있습니다. 이럴 경우 querydsl로 조회 할 때 dtype을 where 절에서 사용할 수 있는지 궁금합니다. 만약 사용할 수 없다면 실무에 적용할 수 있는 다른 좋은 방법이 있는지 궁금합니다.
- 미해결실전! Querydsl
coalesce를 활용한 조건 질의에 대해서 궁금한게 있습니다
안녕하세요 :) 열심히 찾아보고 찾아봤는데, 잘 모르겠어서 문의글 처음 올려봅니다. coalesce를 활용하여 값이 없을때는 특정 값이 바인딩되도록 하여 비교하는 조건을 작성하려고 합니다. 오라클 쿼리에선 nvl이라는 것을 활용하여 다음과 같은 쿼리가 나오게 하려고 하는데요. nvl(test_code, '01') = '01' Expressions.asEnum(entity.testCode.coalesce(TestCode.DEFAULT)).eq(testCode.DEFAULT) 이렇게 조건을 걸었을때 쿼리에선 다음과 같이 나옵니다 nvl(table.test_code, '<byte[]>') = '<byte[]>' 해당 엔티티에는 enum을 위해 converter도 설정되어 있는데 byte[]로 나오는게 이해되지 않습니다. 할 수 없이 enum을 string으로 변경하여 비교하도록 하니 쿼리는 동작합니다. Expressions.asString(entity.testCode.stringValue()).coalesce('01').asString().eq('01') 아래 코드와 같이 쿼리가 나옵니다. nvl(to_char(table.test_code), '01')='01' 이미 varchar형태인 컬럼을 to_char로 변경해서 돌리는게 비효율적인 것 같습니다. 조언 부탁드립니다
- 미해결실전! Querydsl
@QueryProjection Set<String> 타입
안녕하세요 프로젝트를 해보고있습니다. @QueryProjection 으로는 Set<String> 타입을 QueryDsl을 사용해서 new Operation으로 사용할 방법은 없나요??