728x90
1. JPQL을 사용하여 여러 개의 Member 삭제하기
Spring Data JPA에서 JPQL을 활용하여 여러 개의 Member 엔티티를 한 번에 삭제하려면 @Modifying과 @Query를 사용해야 합니다.
@Repository
public interface MemberRepository extends JpaRepository<Member, Long> {
@Modifying
@Query("DELETE FROM Member m WHERE m.id IN :memberIds")
void deleteMembersByIds(@Param("memberIds") List<Long> memberIds);
}
✅ 설명
- @Modifying: DELETE, UPDATE 같은 변경 쿼리를 실행할 때 필수로 추가해야 합니다.
- IN (:memberIds)를 사용하여 여러 개의 ID를 한 번에 삭제할 수 있습니다.
- @Transactional을 함께 사용하여 트랜잭션을 관리해야 합니다.
📌 서비스 계층에서 사용 예시
@Service
@RequiredArgsConstructor
@Transactional
public class MemberService {
private final MemberRepository memberRepository;
public void deleteMembers(List<Long> memberIds) {
memberRepository.deleteMembersByIds(memberIds);
}
}
이제 여러 개의 Member를 효율적으로 삭제할 수 있습니다.
2. QueryDSL에서 동적 검색 조건 처리하기
QueryDSL을 사용하여 검색 조건을 동적으로 적용할 때 null 값을 어떻게 처리해야 할까요?
❌ 잘못된 코드
private BooleanBuilder searchPredicate(MemberSearchDto cond) {
return new BooleanBuilder().and(memberNameEq(cond.getName()))
.and(ageGoe(cond.getMinAge()))
.and(ageLoe(cond.getMaxAge()))
.and(teamNameEq(cond.getTeamName()));
}
이 코드에서는 cond.getMinAge()가 null이면 ageGoe(null)이 실행되면서 Hibernate에서 예상치 못한 동작을 할 수 있습니다.
(테스트 해본 결과 잘못된 코드로 보기 어렵다. 단, MemberSearchDto에서 minAge와 maxAge의 타입을 int 원시타입이 아닌 Integer 객체 타입으로 줘야 Null 일 때, 무시된다. int 타입일 때, 쿼리가 무시되지않고, where절에서 조건을 탄다.)
✅ 올바른 해결 방법: null 체크 후 조건 추가
private BooleanExpression searchPredicate(MemberSearchDto cond) {
return Expressions.allOf(
memberNameEq(cond.getName()),
ageGoeNullable(cond.getMinAge()),
ageLoeNullable(cond.getMaxAge()),
teamNameEq(cond.getTeamName())
);
}
private BooleanExpression ageGoeNullable(Integer minAge) {
return minAge != null ? member.age.goe(minAge) : null;
}
private BooleanExpression ageLoeNullable(Integer maxAge) {
return maxAge != null ? member.age.loe(maxAge) : null;
}
이 방식의 장점은 null인 경우 자동으로 해당 조건을 제거한다는 것입니다.
🔥 결론
- JPQL DELETE에서는 @Modifying과 @Query를 함께 사용해야 합니다.
- BooleanBuilder를 사용할 때는 null 체크를 해야 불필요한 조건이 제거됩니다.
- BooleanExpression을 활용하면 더 간결한 코드로 동적 쿼리를 구현할 수 있습니다.
이제 Spring Data JPA와 QueryDSL을 더욱 효과적으로 활용할 수 있습니다! 😊
'JPA & Querydsl' 카테고리의 다른 글
| 📝 대규모 시스템을 위한 효율적인 계층형 메뉴 관리 시스템 구축 전략 (Spring Boot, JPA, QueryDSL 활용) (0) | 2025.12.09 |
|---|---|
| QueryDsl을 사용하면서, fetchjoin()을 사용해야 할 때는 언제인가? (0) | 2025.02.25 |
| fetchResults(), fetchCount() deprecated된 이유(Querydsl) (0) | 2024.05.20 |
| Transaction에 대하여 깊이있게.. (1) | 2023.12.28 |
| JPA 연관관계 매핑 (0) | 2023.12.05 |