
학습 목표와 요구사항을 봤을 때,
정렬 기능과 최대로 조회 가능한 데이터 개수 제한을 보고
무작정 페이지네이션으로 처리했었다.
그런데 블로그를 작성하면서 생각하니,
'우선은 정렬 기능만 구현하라는 건가?' 싶어서 수정했다.
최근 작성된 순서로 게시글을 정렬하기 위해서는 createdAt 컬럼을 이용해야 한다.
📂 Controller.java
// 게시글 전체 조회 - 페이지네이션❌, 정렬⭕
@GetMapping("/posts")
public ResponseEntity<List<PostResponse>> getAllPosts(){
return postService.getAllPosts();
}
📂 Repository.java
createdAt 컬럼을 기준으로 내림차순한다. @Query("SELECT p FROM Post p ORDER BY p.createdAt DESC")
List<Post> findAll();
📂 Service.java
findAll()로 조회한 모든 게시글을 Response DTO 형태로 변환하고 반환하면 끝! // 게시글 전체 조회 - 페이지네이션❌, 정렬⭕
@Transactional(readOnly = true)
public ResponseEntity<List<PostResponse>> getAllPosts(){
List<PostResponse> postResponses = postRepository.findAll().stream()
.map(PostResponse::new)
.toList();
return ResponseEntity.status(HttpStatus.OK).body(postResponses);
}
📂 Repository.java
List<Post> findAllByOrderByCreatedAtDesc();
📂 Service.java
// 게시글 전체 조회 - 페이지네이션❌, 정렬⭕
@Transactional(readOnly = true)
public ResponseEntity<List<PostResponse>> getAllPosts(){
List<PostResponse> postResponses = postRepository.findAllByOrderByCreatedAtDesc().stream()
.map(PostResponse::new)
.toList();
return ResponseEntity.status(HttpStatus.OK).body(postResponses);
}
JPQL은 SQL과 유사하지만 테이블이 아니라 엔티티 객체를 대상으로 작성하는 쿼리 언어JPQL은 테이블이 아닌 엔티티 클래스와 필드를 기준으로 작성한다.JOIN, GROUP BY, HAVING 등의 사용이 가능하다.@Query는 Spring Data JPA에서 사용자 정의 JPQL을 작성할 때 사용하는 어노테이션@Query를 사용하면 JPA가 제공하는 메서드 대신 명시적으로 정의한 쿼리를 실행할 수 있다.@Param은 JPQL 또는 네이티브 쿼리에서 사용되는 바인딩 변수와 메서드 매개변수를 연결하는 역할 @Query("SELECT u FROM User u WHERE u.username = :username")
List<User> findByUsername(@Param("username") String username);
Query Method는 Spring Data JPA가 메서드 이름을 분석해 자동으로 SQL을 생성하는 기능findBy, findAllBy, countBy, existBy 등의 키워드를 사용해 데이터를 조회한다.| 메서드 | SQL 변환 |
|---|---|
findByUsername(String username) | WHERE username = ? |
findByAgeGreaterThan(int age) | WHERE age > ? |
findByEmailContaining(String email) | WHERE email LIKE %?% |
| 메서드 | SQL 변환 |
|---|---|
findByUsernameAndAge(String usernanme, int age) | WHERE username = ? AND age = ? |
findByUsernameOrEmail(String username, String email) | WHERE username = ? OR email = ? |
| 메서드 | SQL 변환 |
|---|---|
findByUsernameOrderByCreatedAtDesc(String username) | WHERE username = ? ORDER BY created_at DESC |
findAllByOrderByCreatedAtAsc() | ORDER BY created_at ASC |
| 메서드 | SQL 변환 |
|---|---|
findByUsername(String username) | WHERE username = ? |
findByAgeGreaterThan(int age) | WHERE age > ? |
findByEmailContaining(String email) | WHERE email LIKE %?% |
| 메서드 | SQL 변환 |
|---|---|
findByEmailIsNull() | WHERE email IS NULL |
findByEmailIsNotNull() | WHERE email IS NOT NULL |
| 메서드 | SQL 변환 |
|---|---|
findTop3ByOrderByCreatedAtDesc() | ORDER BY created_at DESC LIMIT 3 |
findFirstByOrderByAgeASC() | ORDER BY age ASC LIMIT 1 |
| 비교 항목 | @Query(w. JPQL) | Query Method |
|---|---|---|
| 쿼리 생성 방식 | JPQL을 직접 작성 | Spring Data JPA가 자동 생성 |
| 유지보수성 | 엔티티 변경 시 수동 수정 필요 | 엔티티 변경 시 자동 반영 |
| 복잡한 쿼리 | 복잡한 쿼리 작성 가능 | JOIN, GROUP BY 등의 작성이 어려움 |
| 성능 차이 | JPQL 최적화 | Spring Data JPA 최적화 |
findBy, findAllByOrderBy 등 쿼리 메서드 사용JOIN, GROUP BY, HAVING 등) : @Query(w. JPQL) 사용