[QueryDSL] 활용 (JPA + QueryDSL)
실제로 애플리케이션을 설계할 때는 Repository 계층을 만들고 Repository를 통해 데이터베이스와 상호작용한다.
먼저 Spring Data JPA 기술 없이 순수 JPA와 QueryDSL 만 사용해서 Repository를 설계해보자.
@Repository
public class MemberJpaRepository {
private final EntityManager em;
private final JPAQueryFactory queryFactory;
public MemberJpaRepository(EntityManager em) {
this.em = em;
this.queryFactory = new JPAQueryFactory(em);
}
public void save(Member member) {
em.persist(member);
}
public Optional<Member> findById(Long id) {
Member findMember = em.find(Member.class, id);
return Optional.ofNullable(findMember);
}
public List<Member> findAll() {
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
public List<Member> findByUsername(String username) {
return em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", username)
.getResultList();
}
public List<Member> findAll_Querydsl() {
return queryFactory
.selectFrom(QMember.member).fetch();
}
public List<Member> findByUsername_Querydsl(String username) {
return queryFactory
.selectFrom(QMember.member)
.where(QMember.member.username.eq(username))
.fetch();
}
}
QueryDSL 기술을 사용하면 JPA 로만 작성할 때 보다 좀 더 간편하게 작성할 수 있다.
추가로 BooleanBuilder를 사용해 동적 쿼리를 구현하자.
public List<MemberTeamDto> searchByBuilder(MemberSearchCondition condition) {
BooleanBuilder builder = new BooleanBuilder();
if (hasText(condition.getUsername())) {
builder.and(member.username.eq(condition.getUsername()));
}
if (hasText(condition.getTeamName())) {
builder.and(team.name.eq(condition.getTeamName()));
}
if (condition.getAgeGoe() != null) {
builder.and(member.age.goe(condition.getAgeGoe()));
}
if (condition.getAgeLoe() != null) {
builder.and(member.age.loe(condition.getAgeLoe()));
}
return queryFactory
.select(new QMemberTeamDto(
member.id,
member.username,
member.age,
team.id,
team.name))
.from(member)
.leftJoin(member.team, team)
.where(builder)
.fetch();
}
DTO를 사용해 Member와 Team 정보를 함께 조회하는 예시이다.
MemberSearchCondition 객체를 만들어 검색 조건을 간단하게 표현했고, StringUtils의 hasText 함수를 사용해 문자열이 null인지 확인한 후 BooleanBuilder를 만들어준다.
쿼리를 작성할 때 builder를 추가해야 함을 잊지 말자.
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();
}
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);
}
where 다중 파라미터를 사용해서 동적 쿼리를 구현해도 된다.
반응형
'Spring > QueryDSL' 카테고리의 다른 글
[QueryDSL] 활용 (Spring Data JPA + QueryDSL) (1) | 2023.01.11 |
---|---|
[QueryDSL] 중급 문법 (0) | 2023.01.10 |
[QueryDSL] 기본 문법 (0) | 2023.01.09 |
댓글
이 글 공유하기
다른 글
-
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
[QueryDSL] 활용 (Spring Data JPA + QueryDSL)
2023.01.11 -
[QueryDSL] 중급 문법
[QueryDSL] 중급 문법
2023.01.10 -
[QueryDSL] 기본 문법
[QueryDSL] 기본 문법
2023.01.09