스프링부트/JPA

[Spring] Query DSL 문법 정리-2

삼록이 2025. 9. 4. 21:07

1.수정 쿼리

jpaQueryFactory
    .update(post)
    .set(post.readYn, true) ->set()안에서는 변경할 필드, 변경할 값을 넣어야함
    .where(post.id.eq(postId))
    .execute();   // ← 이게 없으면 쿼리 안 나감

 

여기서 여러 필드에 대해 수정이 들어가면

예를 들어, post.readYn 뿐만 아니라 제목도 수정이 필요하다면, 아래처럼

.set().set()이렇게 연이어서 추가하면 된다.

jpaQueryFactory
    .update(post)
    .set(post.readYn, true) ->set()안에서는 변경할 필드, 변경할 값을 넣어야함
    .set(post.title, "변경할 제목")
    .where(post.id.eq(postId))
    .execute();   // ← 이게 없으면 쿼리 안 나감

 

혹은 필요한 부분에 대해서만 수정이 필요하다면 JPAUpdateClause라는 클래스를 사용할 수도 있다.

JPAUpdateClause는 .update().set().where() 부분에서 set()부분을 계속 해서 빌드해나갈 수 있는 것이 특징이다 

사용 예는 아래와 같다.

  public void updateCompanyPage(Long postId, PostUpdateReqDto dto) {
       //JPAUpateClause는 .set()을 여러번 체이닝 할 수 있도록 하는 객체.
        JPAUpdateClause updateClause = jpaQueryFactory.update(companyPage);

        if(dto.getTitle() !=null){
            updateClause.set(post.title,dto.getTitle());
        }
        if(dto.getWriter() != null){
            updateClause.set(post.writer,dto.getWriter());
        }
        if(dto.getContent() != null){
            updateClause.set(post.content,dto.getContent());
        }
        if(dto.getCategory() != null){
            updateClause.set(post.category, dto.getCategory());
        }
       
        //업데이트 쿼리 실행
        updateClause.where(post.id.eq(postId)).execute();
        //쿼리 dsl의 update()는 JPA의 영속성 컨텍스트를 건너띄고 바로 db에 반영 그래서 수동으로 clear()해서 영속성컨텍스트와 db의 씽크 맞춤
        entityManager.clear();

    }
}

 

 

2.존재 여부 확인

 

이 데이터가 존재하는 지 아닌 지 여부를 확인할 때 실제 SQL문에서 SELECT 1~ 이런식으로 쓴 적이 있을 것이다.

Query DSL에서는 .selectOne()을 사용하면 된다.

Integer exists = jpaQueryFactory
    .selectOne()
    .from(user)
    .where(user.loginId.eq("kim"))
    .fetchOne();

 

유저테이블에 아이디가 kim인  유저가 존재한다면 exists =1이 될 것이고 없다면 null이 된다.

이거를 곧장 Boolean으로 받는 방법도 있다.

Boolean exists = jpaQueryFactory
    .selectOne()
    .from(user)
    .where(user.loginId.eq("kim"))
    .fetchFirst() != null;

.fetchFirst()는 첫번째 row만을 가져온다. 따라서 여기서는 존건을 만족하는 row가 있다면 1 없다면 마찬가지로 null이 반환되는 상황에서 이 결과값이 !=null 로 비교한다. 

즉 결과가 1이면 null이 아니므로 true. null이면 !=null을 충족시키지 못하므로 false가 리턴되고 그것이 exists값이 되는 것이다.

 

3.JOIN

쿼리 DSL에서 JOIN을 맺을 수 있는 방식에는 2가지 문법이 있다

 

첫번째.

 

jpaQueryFactory
    .select(post.id)
    .from(post)
    .join(user).on(post.writer.id.eq(user.id)) 
    .where(user.loginId.eq("kim"))
    .fetch();

 

두번째.

jpaQueryFactory
    .select(post.id)
    .from(post)
    .join(post.writer, user) 
    .where(user.loginId.eq("kim"))
    .fetch();

 

첫번째는 일반적으로 일반적인 SQL에서 JOIN~ON~하듯이 진행했고,

두번째는 on없이 join()내부에 바로 조인하는 컬럼을 기준을 나열했다.

첫번째로 하든 두번째로 하든 사실 내부적으로는 똑같은 쿼리가 날라가기 때문에 성능의 차이는 없다.

다만 두번째는 JPA에서 연관관계가 맺어져 있을 때 그걸 인식해서 사용되는 법이라,
@ManyToOne, @OneToMany, @OneToOne, @ManyToMany와 같은 관계 어노테이션이 붙어있어야만 사용될 수 있다.