실전! Querydsl

실전! Querydsl

(24개의 수강평)

454명의 수강생
월29,333원
88,000원
3개월 할부시
지식공유자 · 김영한
41회 수업· 총 6시간 24분수업
평생 무제한 시청
수료증 발급 강의
수강 난이도 중급
박승일 Park 프로필

동적쿼리 where절 파라미터 조합 질문입니다. 박승일 Park 2일 전

private BooleanBuilder ageCond(Integer ageGoe, Integer ageLoe) {
BooleanBuilder booleanBuilder = new BooleanBuilder();
return booleanBuilder
.and(ageGoe(ageGoe))
.and(ageLoe(ageLoe))
.and(teamNameEq("teamB"));
}

private BooleanExpression usernameEq(String username) {
return isEmpty(username) ? null : member.username.eq(username);
}
private BooleanExpression teamNameEq(String teamName) {
return isEmpty(teamName) ? null : team.name.eq(teamName);
}
private BooleanExpression ageGoe(Integer ageGoe) {
return ageGoe == null ? null : member.age.goe(ageGoe);
}
private BooleanExpression ageLoe(Integer ageLoe) {
return ageLoe == null ? null : member.age.loe(ageLoe);
}

ageCond 처럼 여러 조건 조합시 null처리를 조금 이쁘게 하고 싶은데 다른 생각이 안나서 booleanBuilder로 해봤더니 별 문제는 없는데요, 혹시 다른 깔끔한 방법이 있을까요?

1
google_user 프로필

공통 코드 테이블을 운영 할 경우 엔티티 설계를 어떻게 하는게 좋을까요? google_user 3일 전

안녕하세요 

김영환님 스프링부트와 jpa 모든 강의들 너무나 잘 들었습니다 

그동안 2tier방식의 앱(oracle, PowerBuilder) 만을 개발하다

스프링부트와 data jpa를 이용한 개발을 하려니 참 막막 했는데

개념을 잡는데 많은 도움이 되었습니다 ^^

한가지 질문을 드리고자 합니다 

데이타베이스 관점에서 여러 테이블에서 필요에 맞는 공통 코드들을 

하나의 테이블에 모아놓은 후 구분 코드와 세부 코드해서 설계를 해보려 하는데 

이럴경우 엔티티 설계를 어떻게하는것이 좋은 방법인지 궁금합니다. 

(enum 이나 각 코드에 맞는 엔티티를 다 생성하는것이은 너무 많아보여서요)

혹시 참고 할 만한 자료가 있음 추천도 부탁드립니다^^

좋은 하루 되세요 

2
OMG 프로필

QueryDSL 참고 자료 질문있습니다! OMG 3일 전

안녕하세요 영한님.

QueryDSL이 공개된지는 꽤 오래 된 거 같은데

생각보다 관련 자료가 인터넷에 많이 없는 거 같더라구요!

영한님 강의가 아니였다면 QueryDSL을 익히기 끔찍했을거 같습니다...

QueryDSL을 공부하실 때 "공식문서"를 "제외"하고 참고하신 자료가 있으실까요..?!

제가 찾아본 바로는 국내 서적에서는 간단하게 소개하는 정도, 간단하게 적용한 예제 정도는 보았는데 그 이상을 다루는 거 같지는 않은데

QueryDSL을 공부하시거나 실무에 적용하실 때 참고하신 자료가 있다면 소개해주실수 있을까요?!?!

1
wxxsox lee 프로필

엔티티 설계 질문 wxxsox lee 4일 전

안녕하세요. 강사님.

강사님의 강의를 듣고  엔티티 설계 중에서 궁금한 사항이 있어 질문 남깁니다.

제가 개발하는 엔티티 구조는 1:N 관계로 Parent : Child 구주로 이루어져있습니다.
Parent - Child 구조의 하나의 어그리게잇 으로 생각하고 있으며 하나의 ParentRepository를 통해서 Parent와 Child를 관리하려 합니다. 또한, Parent가 삭제되면 모든 Child도 삭제되어야만 합니다.

현재, 저는 Parent 클래스 내 OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)로 Parent와 Child 간 단방향 매핑을 했으며, Parent가 삭제되면 모든 Child가 삭제가 되도록 개발중입니다.
또한, Child를 저장하고 싶으면 Parent를 find 후 Child를 add하는 방식으로 Child를 저장하고있습니다.

그런데, Parent를 find 시 Child가 Collection이므로 페치 조인이 어려워 @OneToMany에서 @ManyToOne 단방향으로 변경하려하는 와중에 두가지 질문이 있습니다,

첫째로, 어그리게잇 내 유일한 ParentRepository내에서 어떻게 하면 Child를 저장할 수 있을까요? 기존에는 Parent를 가져와 add하는 방식으로 구현했습니다. ParentRepository 에서 entity manager를 주입해 persist해줘야 할까요?

둘째로, Parent 삭제시 어떻게 하면 모든 Child를 삭제할 수 있을까요..당장 생각하는 방안은 Service Layer에서 관련된 Child를 지우고 그 다음 Parent를 삭제하는 방법을 생각하고있습니다.

위 질문에 답변주시면 정말 감사하겠습니다.
그리고, 제공해주신 강의덕분에 실무에 엄청난 도움을 얻고있습니다, 노하우를 공유해주셔서 진심으로 감사합니다.

3
Bulbasaur 프로필

[수정, 삭제 벌크연산] subtract 메서드 Bulbasaur 9일 전

안녕하세요 .강사님

작은 부분이지만, 다른 분들도 아시면 좋을 것 같아서 조심스럽게 적어 봅니다.

[수정, 삭제 벌크연산] 강의 중 더하기는 add(1), 빼기는 add(-1)하면 된다고 알려주셨는데,

또한 subtract란 메서드로도 뺄셈 연산이 가능하여 전달 드립니다.

항상 좋은 강의 감사드립니다 ^^!

많은 도움 받고 있습니다.  

@Test
public void bulkAdd(){
long count = queryFactory
.update(member)
.set(member.age, member.age.add(1))
.execute();
}

@Test
public void bulkSubtract(){
long count = queryFactory
.update(member)
.set(member.age, member.age.subtract(1))
.execute();

} 

2
김형진 프로필

DTO 변환 질문입니다. 김형진 9일 전

User라는 entity에서 AuthorityDTO라는 클래스로 변환을 하려고 하는 데 에러가 나서 원인을 혹시 아시나요?

bean, fields, constructor 전부 같은 에러가 나네요.

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [com.illunex.invest.user.persistence.entity.User] to type [com.illunex.invest.api.core.user.dto.AuthorityDTO]

public List<AuthorityDTO> findByCompanyIdx(Long companyIdx) {
        QUser user = QUser.user;

        return queryFactory.select(Projections.bean(AuthorityDTO.class
                , user.id
                , user.username
                , user.name
                , user.authorities
                , user.profileImg
                , user.companyIdx))
                .from(user)
                .where(user.companyIdx.eq(companyIdx))
                .fetch();
    }

@NoArgsConstructor
@AllArgsConstructor
@Getter @Setter
public class AuthorityDTO {
    private Long id;
    private String username;
    private String name;
    //private Set<RoleDTO> authorities = new HashSet<>();
    private String profileImg;
    private Long companyIdx;
}

@Entity
@Table(name = "user"
        , indexes = {
            @Index(name = "IDX_USERNAME", unique = true, columnList = "username"),
            @Index(name = "IDX_COMPANY_IDX", columnList = "companyIdx")
})
@NoArgsConstructor
@AllArgsConstructor
@Getter @Setter
@Builder
public class User implements UserInterface {
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(nullable = false, updatable = false)
    private Long id;
    @Column(nullable = false, unique = true)
    private String username;
    @Column(nullable = false)
    private String password;

    private String name;
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name = "user_role",
            joinColumns = @JoinColumn(name = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> authorities = new HashSet<>();

    private String profileImg;

    private String vender;

    private Long companyIdx;

    private Boolean certification = false;

    private String token;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.DETACH, mappedBy = "user")
    private List<Signature> signatures = new ArrayList<>();

    public static User createUser(String username, String password, String name, String vender, String token, Long companyIdx) {
        return getUserBuilder(username, password, name, vender, token, companyIdx)
                .authorities(Role.initRoles())
                .build();
    }

    public static User createCompanyAdminUser(String username, String password, String name, String vender, String token, Long companyIdx) {
        return getUserBuilder(username, password, name, vender, token, companyIdx)
                .authorities(Role.companyAdminRoles())
                .build();
    }

    private static UserBuilder getUserBuilder(String username, String password, String name, String vender, String token, Long companyIdx) {
        return User.builder()
                .username(username)
                .password(encodePassword(password))
                .name(name)
                .vender(vender)
                .certification(false)
                .token(token)
                .companyIdx(companyIdx);
    }

    public static String encodePassword(String password) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder.encode(password);
    }

    public static boolean matchPassword(String prePassword, String inputPassword) {
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder.matches(inputPassword, prePassword);
    }

    @Override
    public Collection<Role> getAuthorities() {
        return authorities;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

1
이요한 프로필

AttributeConverter 관련 질문입니다! 이요한 10일 전

안녕하세요! QueryDsl 강의 엊그제 완강하였습니다~!

이제 곧 회사에서 QueryDsl 을 적용하려 하는데 정말 큰 도움이 되었습니다 감사합니다!

이번에 드릴 질문은 다름 아니라 AttributeConverter에 관한 질문입니다!

데이터베이스에 Json 타입의 필드를 AttributeConverter를 사용해 커스텀한 클래스로 받아왔을때 트랜잭션이 끝날때 더티체킹이 일어나 업데이트를 하는 이슈가 존재했습니다.

이 때 더티체킹이 일어나는 이유는 어떤 상황 때문일까요?
그리고 이 상황에서 .equals를 오버라이딩해서 더티체킹을 해제해주는 방안을 찾았는데 이 방법 외에 더 괜찮은 방법이 있을까요?
혹시 몰라 제가 참고한 링크도 남기겠습니다..!
https://medium.com/@paul.klingelhuber/hibernate-dirty-checking-with-converted-attributes-1b6d1cd27f68


그리고 하나 더 궁금한 것이 AttributeConverter의 동작이
DB에서 find할때는 convertToEntityAttribute,
DB에 flush 할때는 convertToDatabaseColumn
메소드가 실행 될 것이라 생각했는데 find만 하더라도 두 메소드를 여러번 왔다갔다 하는데 이 동작방식에 대한 궁금증이 있습니다!

항상 좋은 강의와 답변에 감사드립니다!

1
양우성 프로필

querydsl에서 동적 정렬하는 팁이 있을까요? 양우성 10일 전

예를 들어 Pageable 같은 경우와 같이 client에서 입력한 컬럼과 내림 또는 올림으로 정렬을 하고 있는데 이와 같이 할수 있는 방안이 있나 궁금해서요.

2
java_oop 프로필

연관관계 없는 상태에서 1:N Projectons이 가능한가요? java_oop 12일 전

class Member {

  private Long id;

  private Long TeamId

  private String name;

}



class Team {

  private Long id;

  private String name;

}

이렇게 연관관계 없이 ID만 참조하는 경우 Query DSL Projectons을 사용해서 Team List으로보면서 거기에 속한 Member들 또한 List로 볼 수 있을까요?

[
  {
    "team_id": 1,
    "team_name": "team_A",
    "members": [
      {
        "id": 1,
        "name": "member_name_1"
      },
      {
        "id": 2,
        "name": "member_name_2"
      },
      {
        "id": 3,
        "name": "member_name_3"
      }
    ]
  },
  {
    "team_id": 2,
    "team_name": "team_A",
    "members": [
      {
        "id": 4,
        "name": "member_name_4"
      },
      {
        "id": 5,
        "name": "member_name_5"
      },
      {
        "id": 6,
        "name": "member_name_6"
      }
    ]
  }
]

1
Half Lemon 프로필

Dto 설계 문의 Half Lemon 20일 전

안녕하세요. 샘플강의 보고 감명받아 영환님 모든 강의를 수강하고 몇일 전 완강을 했습니다. 

좋은 강의 다시 한번 감사합니다. 

다름이 아니라 문의드릴 내용은 다음과 같습니다.  Dto 설계와 구현인데요 

public class ScheduleDto {
 ...
  private List<WatchDtowatchs;
@QueryProjection
  public ScheduleDto(...List<WatchDtowatchs) {
...
this.watchs = watchs;
 }

위와 같이 Dto구성하고,

검색 Repository에서 아래와 같이 watchs 를 구성한다고 했을때 

@Override
  public Page<ScheduleDtosearchPage(ScheduleSearchCond condPageable pageable) {
    List<ScheduleDtocontent = qf.selectnew QScheduleDto(
                                   ...
                                    schedule.watchs // << [이부분 구성을 어떻게 처리해야하는지 ??]
                                    ))
                                  .from(schedule)
                                  .fetch();

schedule.watchs는 List 인데, 어떻게 작성되어야 하는지 궁금합니다. 

그리고 Dto 설계상 "List<someDto> xxx" 로 멤버변수를 만들면 안되는지도 궁금합니다.

강의에 해당 예시가 안보여서, 설계가 문제있는지도 궁금해서요. 

아무쪼록 요즘같은 시기에 건강 유의하시고, 다음 강의도 기대하겠습니다. 

개인적으로는 결제 관련 백엔드 강의면 좋겠다 싶은 희망사항도 있습니다. 

수고하세요 ^^

1
김태수 프로필

DTO 관련 질문입니다. 김태수 20일 전

먼저 좋은 강의 감사합니다 :)

매 강의마다 좋은 내용을 알려주셔서 감사합니다.

하나의 Entity에서 여러 서비스 로직을 실행하기 위해

    1) 각 서비스에 맞는 DTO를 생성하는 방법과

    2) 통합 DTO를 만든뒤 그 DTO에서 각 서비스에 필요한 요소들을 빼오는 방법

제가 생각한 위 두가지 방법의 단점은 아래와 같습니다.

    1) DTO를 너무 많이 생성함

    2) 통합 DTO 중 사용하는 서비스의 필요 요소가 적으면 전부 DTO로 담는것이 비효율적임

질문 내용입니다!

    1) 혹시 제가 생각한 두 방법의 단점이 맞는지 궁금합니다.

    2) 만약 위 상황처럼 하나의 Entity를 여러 서비스에서 이용할 때 DTO를 어떤 방식으로 구성하면 좋을지 궁금합니다.

감사합니다.

2
정윤성 프로필

@PostConstruct와 @Transactional 분리 정윤성 21일 전

@PostConstruct와 @Transactional 분리해야 하는이유를 간단히 짚고넘어가셔서 그런데 좀더 자세하게 설명해주실 수 있으신가요 ?? ㅠㅠ

1
정윤성 프로필

Repository를 src.main패키지가아닌 build패키지에 만드신이유가 궁금합니다 정윤성 21일 전

Repository를 src.main이 아닌 build쪽에 만드신이유가 QueryDSL을 쓰다보면 자연스럽게 Q객체에 의존하기 때문에 아키텍처관점에서 좀더 가까이 있는 곳에 만들어 보기쉽게 하기 위함이신건가요 ??

1
정윤성 프로필

외래키설정 ConstraintMode 정윤성 22일 전

ConstraintMode.NO_CONSTRAINT를 이용해서 조인컬럼을 지정할경우 논리적으로만 맺고 물리적인 외래키를 맺지않는걸로 알고있는데 이러한 방법으로 외래키를 지정하는게 좋은방법인가요 ?

3
Dongwoo Seo 프로필

@Transactional 질문입니다. Dongwoo Seo 27일 전

안녕하세요.

강의잘듣고있습니다.

@Transactional 사용 시점이 궁금해서 질문남깁니다.

1. 강의에서 Test에 @Trasactional을 적용했는데 Test에 적용한 이유가 무엇인가요? 보통 Service 클래스를 구현할 때 각각 Trasnactional 어노테이션을 붙여주긴 하는데 Test 클래스 전역에 Trasnactional 을 붙이면 얻는 이점이 있나요?

3
지식공유자 되기
많은 사람들에게 배움의 기회를 주고,
경제적 보상을 받아보세요.
지식공유참여
기업 교육을 위한 인프런
“인프런 비즈니스” 를 통해 모든 팀원이 인프런의 강의들을
자유롭게 학습하는 환경을 제공하세요.
인프런 비즈니스