요구 사항들을 정리하면,
즉,
전체적인 로직에서 보면 repository엔 jpql 기반 검색 메서드 추가해주고, service엔 if문을 활용해서 여러 개의 jpql을 사용할 수 있게하고, Contoroller에서 새로운 검색 api를 추가하면 되는 것이다.
일단 해당 개념을 알아야 수정이 가능하지 않습니까!? ㅎㅎ
그래서 준비했습니다.
엔티티 매핑 (@Entity, @Id, @GeneratedValue)
연관관계 (@OneToMany, @ManyToOne, @JoinColumn)
FetchType.LAZY와 Fetch Join 활용
JPQL & QueryDSL 개념
@Query 사용법 → JPQL 작성법
동적 쿼리 (Criteria API, QueryDSL)
페이징 (Pageable, Page<T>
활용)
@RestController, @RequestParam, @RequestBody, @PathVariable
ResponseEntity 활용 (에러 처리 포함)
JWT 개념 (Claims, Header, Payload)
토큰 발급 및 검증 (JwtUtil, Filter 활용)
Security 적용 (UserDetails, Authentication)
실습 1) Todo 검색 기능 개발
weather, 기간 검색 동적 쿼리 연습
JPQL, @Query 활용
페이징 API 추가 (Page<T>
활용)
@Query("SELECT t FROM Todo t " +
"WHERE (:weather IS NULL OR t.weather = :weather) " +
"AND (:startDate IS NULL OR t.modifiedAt >= :startDate) " +
"AND (:endDate IS NULL OR t.modifiedAt <= :endDate)")
Page<Todo> searchTodos(@Param("weather") String weather,
@Param("startDate") LocalDateTime startDate,
@Param("endDate") LocalDateTime endDate,
Pageable pageable);
실습 2) JWT에 nickname 추가 후 검증
JWT 토큰 생성 시 nickname 추가
JwtFilter에서 nickname 검증 후 request.setAttribute 활용
// JWT 생성 (nickname 추가)
public String createToken(Long userId, String email, String nickname, UserRole userRole) {
return Jwts.builder()
.setSubject(String.valueOf(userId))
.claim("email", email)
.claim("nickname", nickname) // 닉네임 추가
.claim("userRole", userRole)
.signWith(key, signatureAlgorithm)
.compact();
}
// JWT 필터에서 닉네임 검증
String nickname = claims.get("nickname", String.class);
if (nickname == null) {
httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "jwt에 닉네임 정보가 없습니다.");
}
실습 3) Lazy Loading과 Fetch Join 차이 비교
@ManyToOne(fetch = FetchType.LAZY) 와 Fetch Join 차이점 실습
N+1 문제 해결 방법 이해
// Lazy Loading (N+1 발생 가능)
@Query("SELECT t FROM Todo t WHERE t.user.id = :userId")
List<Todo> findTodosByUserId(@Param("userId") Long userId);
// Fetch Join (N+1 해결)
@Query("SELECT t FROM Todo t JOIN FETCH t.user WHERE t.user.id = :userId")
List<Todo> findTodosWithUser(@Param("userId") Long userId);
제가 만약에 해당 내용을 제대로 모른 상태에서 7일이 주어졌다면, 아래와 같이 공부할 것 같습니다.
쉽게 배우는 Spring Boot & JPA
Spring Boot와 JPA를 활용하여 간단한 쇼핑몰을 구축하는 과정을 다룹니다. Java 기본 문법부터 시작하여 웹 서버 백엔드 개발, MySQL 연동, JPA/Hibernate를 통한 데이터 처리 등을 학습할 수 있습니다.
https://codingapple.com/course/spring-boot-jpa/codingapple.com
JPA 프로그래밍 with 스프링부트 - 멀티캠퍼스 과정
Java 애플리케이션의 기존 데이터베이스 연동 방식과 ORM의 기술적 차이점을 이해하고, JPA의 핵심 개념과 동작 원리를 학습할 수 있는 과정입니다.
https://www.multicampus.com/em/enrolment/courseDetaiInfo?corsCd=FA00Z5multicampus.com
우아한형제들 JPA 강의 소감과 적용 사례
우아한형제들에서 진행한 JPA 강의의 소감과 실제 적용 사례를 공유한 글로, 실무에서 JPA를 어떻게 활용하는지에 대한 인사이트를 제공합니다.
https://techblog.woowahan.com/2598/techblog.woowahan.com
',', <join>, FETCH, GROUP, HAVING, ORDER or WHERE expected, got '('
?? 잘 작성한 것 같은데 뭐가 문제지 ? 또르르르르르륵 검색~~~
문법적 오류 때문입니다.
조건문을 작성할 때, 공백이 없거나, WHERE 바로 뒤에 괄호가 있는 경우 JPQL 문법 오류가 발생할 수 있습니다.
참고로 컨트롤러는
튜터님의 작성 코드를 토대로 추가해서 구현해봤습니다.