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와 같은 관계 어노테이션이 붙어있어야만 사용될 수 있다.
'스프링부트 > JPA' 카테고리의 다른 글
| [Spring]@Transactional 어노테이션 제대로 알고 쓰자(+JPA, MyBatis) (2) | 2025.12.02 |
|---|---|
| [Spring] QueryDSL로 서브쿼리 사용-JPAExpressions (0) | 2025.11.25 |
| [Spring] QueryDSL을 통해 DTO로 바로 리턴 받기, 리스트 매핑받기 (4) | 2025.08.31 |
| [Spring] Query DSL 문법 정리 (1) | 2025.08.26 |
| [Spring] JPA에서의 프록시 객체-불필요한 SELECT 쿼리 최소화 방법 (2) | 2025.08.10 |