일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- EC2
- 테스트메소드
- subquery
- 외부키
- Query
- 포트
- 서브쿼리
- ubuntu
- 커밋메세지수정
- MySQL
- WeNews
- 참조키
- 적용우선순위
- appspec
- 예약
- 컨테이너실행
- 네이티브쿼리
- appspec.yml
- docker명령어
- 테스트
- 메소드명
- application.yml
- 추후정리
- 2 > /dev/null
- 메세지수정
- querydsl
- ㅔㄴ션
- AuthenticationEntryPoint
- 검색
- foreignkey
- Today
- Total
제뉴어리의 모든것
[JPA] Spring Data JPA와 QueryDSL (2) 본문
@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);
}
'querydsl' 카테고리의 다른 글
querydsl이 왜 필요한가 외의 유용한 설명들 (0) | 2021.03.18 |
---|---|
querydsl Gradle 설정 (0) | 2021.03.18 |
[JPA] Spring Data JPA와 QueryDSL (1) (0) | 2021.03.18 |