QueryDSL
QueryDSL 소개
- Entity의 매핑 정보를 활용하여 쿼리를 객체 또는 함수로 작성.
- 주요 구성:
- Q클래스: Entity의 쿼리 전용 클래스.
- JPAQueryFactory: Q클래스를 사용하여 쿼리를 생성 및 실행.
QueryDSL 적용 방법
- JPAQueryFactory Bean 등록:
- @Configuration public class JPAConfiguration { @PersistenceContext private EntityManager entityManager; @Bean public JPAQueryFactory jpaQueryFactory() { return new JPAQueryFactory(entityManager); } }
- 쿼리 작성:
- @Autowired private JPAQueryFactory queryFactory; public List<User> selectUserByUsernameAndPassword(String username, String password) { QUser user = QUser.user; return queryFactory.selectFrom(user) .where(user.username.eq(username) .and(user.password.eq(password))) .fetch(); }
예제: 멘션된 쓰레드 조회
- 조건: 내가 멘션된 쓰레드, 정렬 기준은 멘션된 시간 기준 내림차순.
- 출력: 채널명, 작성자 정보, 본문, 이모지 정보, 댓글 정보 등.
public List<ThreadDetails> findMentionedThreads(Long userId) {
QThread thread = QThread.thread;
QMention mention = QMention.mention;
return queryFactory
.select(
Projections.bean(ThreadDetails.class,
thread.channel.name.as("channelName"),
thread.user.username.as("authorName"),
thread.user.profileImageUrl.as("authorProfileImage"),
thread.message.as("message"),
thread.emotions.any().body.as("emotions"),
thread.comments.any().message.as("commentMessages")
))
.from(thread)
.join(thread.mentions, mention)
.where(mention.user.id.eq(userId))
.orderBy(mention.createdAt.desc())
.fetch();
}
Auditing
Auditing 소개
- 엔티티 생성 및 수정 시 자동으로 작성자와 시간을 기록.
적용 방법
- @EnableJpaAuditing 추가:
- @EnableJpaAuditing(auditorAwareRef = "userAuditorAware") @SpringBootApplication public class Application {}
- 공통 Base 클래스 작성:
- @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public class BaseTimeEntity { @CreatedDate private LocalDateTime createdAt; @LastModifiedDate private LocalDateTime modifiedAt; @CreatedBy @ManyToOne private User createdBy; @LastModifiedBy @ManyToOne private User modifiedBy; }
- AuditorAware 구현:
- @Service public class UserAuditorAware implements AuditorAware<User> { @Override public Optional<User> getCurrentAuditor() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null || !authentication.isAuthenticated()) return Optional.empty(); return Optional.of(((UserDetailsImpl) authentication.getPrincipal()).getUser()); } }
Dynamic Insert/Update
Dynamic Insert
- @DynamicInsert:
- Insert 쿼리에서 null 값을 제외한 필드만 포함.
@DynamicInsert
public class User {
private String username;
private String password;
}
적용 전:
insert into users (username, password, id) values (?, ?, ?)
적용 후:
insert into users (username, id) values (?, ?)
Dynamic Update
- @DynamicUpdate:
- Update 쿼리에서 변경된 값만 포함.
@DynamicUpdate
public class User {
private String username;
private String password;
}
적용 전:
update users set username=?, password=? where id=?
적용 후:
update users set username=? where id=?
요약
기능 | 설명 | 적용 예시 |
QueryDSL | - 객체 기반으로 쿼리를 작성하여 가독성과 유지보수성 향상.- JPAQueryFactory와 Q클래스 활용. | - 사용자 검색: selectFrom(user).where(user.username.eq("John")).fetch(); |
Auditing | - 엔티티 생성/수정 시 작성자와 시간을 자동 기록. | - @CreatedBy, @LastModifiedBy를 통해 작성자 자동 기록. |
Dynamic 설정 | - Insert/Update 시 null 값을 제외한 필드만 처리.- 성능 최적화. | - @DynamicInsert, @DynamicUpdate |
'DB > JPA ( Java Persistence API )' 카테고리의 다른 글
[JPA] 테이블 객체 (0) | 2025.01.27 |
---|---|
[JPA] 쿼리 파일 만들기 (QueryMapper) (0) | 2025.01.26 |
[JPA] 데이터베이스 연결 (Driver) (1) | 2025.01.25 |
[JPA] JPA와 Transaction (0) | 2025.01.17 |
[JPA] 지연로딩, 즉시로딩 (0) | 2025.01.15 |