관리 메뉴

제뉴어리의 모든것

[JPA] Spring Data JPA와 QueryDSL (2) 본문

querydsl

[JPA] Spring Data JPA와 QueryDSL (2)

제뉴어리맨 2021. 3. 18. 03:03
@NoRepositoryBean
public class UserRepositoryImpl extends QuerydslRepositorySupport implements CustomUserRepository {

    //QuerydslRepositorySupport 클래스에는 기본생성자가 없음.
    public UserRepositoryImpl() {
        super(User.class);
    }

    @Override
    public List<User> findAllUserByAgeLimit(Integer limitCount) {
        QUser user = QUser.user;
        return from(user)
                .where(user.age.eq(25L))
                .limit(limitCount)
                .fetch();
    }

    @Override
    public List<String> findAllNameByAgeLimit(Integer limitCount) {
        QUser user = QUser.user;
        return from(user)
                .where(user.age.eq(25L))
                .limit(limitCount)
                .select(user.name)
                .fetch();
    }

    @Override
    public List<AccountUserJoinDto> findAllUserGreaterThanAge(Long age) {
        QUser user = QUser.user;
        QAccount account = QAccount.account;

        JPQLQuery<AccountUserJoinDto> query = from(account)
                .innerJoin(account.userId, user)
                .select(Projections.constructor(AccountUserJoinDto.class,
                        user.name,
                        user.age,
                        account.money,
                        account.bankName))
                .where(user.age.gt(age));

        return query.fetch();
    }
}​
public interface CustomUserRepository {
    List<User> findAllUserByAgeLimit(Integer limitCount);
    List<String> findAllNameByAgeLimit(Integer limitCount);
    List<AccountUserJoinDto> findAllUserGreaterThanAge(Long age);
}

Spring Data JPA에서 QueryDSL을 사용하는 2가지 방법과 차이점을 위 포스팅에서 설명했다.

이번 포스팅에서는 2가지 방법중 QueryDslRepositorySupport 클래스를 사용하는 방법을 설명하려 한다.

우선 사용할 entity를 만들자.

@Entity
@Table(name = "tb_user")
@Getter @Setter
@EqualsAndHashCode
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    private Long id;

    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "age", nullable = false)
    private Long age;

}

 

 

@Entity
@Table(name = "tb_account")
@Getter @Setter
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonIgnore
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id", referencedColumnName = "id")
    @JsonIgnore
    private User userId;

    @Column(name = "account")
    private String account_num;

    @Column(name = "money")
    private Double money;

    @Column(name = "bank_name")
    private String bankName;

    @PrePersist
    public void initMoney() {
        this.money = 0D;
    }

}

User와 Account는 1:N 관계이다. 다시 말해, User 하나는 여러개의 Account를 가질수 있다.

이제 이 entity들을 JPA로 가지고 놀기 위해서 Repository를 만들자.

1. 일반적인 Repository를 만드는 방식처럼 JpaRepository<EntityType, IdType>을 extends 하는 인터페이스를 만든다. (UserRepository)

2. CustomEntityTypeRepository를 만든다. (여기서는 CustomUserRepository)

- 이 인터페이스는 Custom한 메서드들을 정의한다.

3. 2번에서 정의한 CustomUserRepository를 구현하는 UserRepositoryImpl 클래스를 만든다. 그리고, 이 클래스는 동시에 QuerydslRepositorySupport 클래스를 상속하도록 한다.

- QuerydslRepositorySupport 클래스를 상속하기 때문에 이제 QueryDsl을 사용할수 있다. (생성자에서 super(EntityType.class)를 호출해야 한다)

- CustomUserRepository에 정의한 Custom 메서드들을 실제로 구현한다. 메서드들을 구현할때 Querydsl을 사용하여 join이나 fetch 등의 기능도 사용 가능하다.

4. 이제 다시 1번에서 만들었던 UserRepository에서 CustomUserRepository 인터페이스를 extends 하도록 한다.

* UserRepository는 JpaRepository를 extends 했기 때문에 JpaRepository가 지원하는 기본 메서드들을 사용 가능하다.

* UserRepository는 CustomUserRepository를 extends 했기 때문에 CustomUserRepository에 선언된 Custom한 메서드들도 사용 가능하다 (내부적으로 UserRepositoryImpl에서 구현한 메서드들을 사용하게 된다).

@Repository
public interface UserRepository extends JpaRepository<User, Long>, CustomUserRepository {
    Optional<User> findByName(String name);
}

 

 

 

출처 : [JPA] Spring Data JPA와 Qu.. : 네이버블로그 (naver.com)

'querydsl' 카테고리의 다른 글

querydsl이 왜 필요한가 외의 유용한 설명들  (0) 2021.03.18
querydsl Gradle 설정  (0) 2021.03.18
[JPA] Spring Data JPA와 QueryDSL (1)  (0) 2021.03.18