[스프링부트 게시판] JPA Specification을 통해 쿼리 조건 다루기

2022. 10. 6. 18:57·🚗 Backend Toy Project/스프링 부트 게시판
  • 이번에 게시판 카테고리를 구현하면서 기존에 Repository에 쿼리를 직접 만들어 사용하던 방식 대신 좀 더 편하고 가독성도 좋은 방식을 알게되어 해당 방식으로 코드를 수정하게 되었습니다.
  • 우선 기존에 사용하던 코드는 아래와 같습니다.
if(category.equals("screenshot")) { 
	model.addAttribute("boards", boardRepository.findAllByCategory(CategoryType.SCREENSHOT, pageable)); 
    return"index"; 
}

if(searchKeyword == null || searchKeyword.isBlank()) {
	model.addAttribute("boards", boardRepository.findAll(pageable)); 
}

if(searchType.equals("nickname")) { 
	model.addAttribute("boards",
	boardRepository.findByUserNicknameContaining(searchKeyword, pageable));
} else { 
	model.addAttribute("boards", boardRepository.findByTitleContaining(searchKeyword, pageable)); }
  • 각각의 변수를 @RequestParam으로 받아서 조건문을 통해 분기해가며 데이터를 필터링하는 방식입니다.

📝 BoardRepository

  • JPA Specification을 사용하기 위해 우선 아래와 같이 해당 Repository에서 JpaSpecificationExecutor를 상속받아야 합니다.
package com.cos.blog.repository;

...

// @Repository
public interface BoardRepository extends JpaRepository<Board, Long>, JpaSpecificationExecutor<Board>{

	...
}

📝 BoardSpecification

  • 다음으로 내가 원하는 조건에 따라 설정한 각각의 함수를 포함하고 있는 클래스를 생성해주었습니다.
package com.cos.blog.specification;

...

public class BoardSpecification {
	
    // 글 제목에 따른 검색
	public static Specification<Board> searchTypeTitle(String searchKeyword) {
        return (root, query, criteriaBuilder) -> criteriaBuilder.like(root.get("title"), "%" + searchKeyword + "%");
    }
	
    // 작성자에 따른 검색
	public static Specification<Board> searchTypeWriter(String searchKeyword) {
        return (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("user").get("nickname"), searchKeyword);
    }
	
    // 카테고리 구분
	public static Specification<Board> equalCategory(String category) {
        return (root, query, criteriaBuilder) -> criteriaBuilder.equal(root.get("category"), category);
    }
	
    // 추천 수에 따른 구분
	public static Specification<Board> recGreaterThan(int recommendCount) {
        return (root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(root.get("recommendCount"), recommendCount);
    }
}

📝 BoardController

  • 실제 사용할 때에는 위에서 정의한 함수를 원하는대로 조합하여 다중 조건 쿼리를 만들 수 있습니다.
Specification<Board> spec = (root, query, criteriaBuilder) -> null;
		
if(!category.isEmpty()) {
    if(category.equals("popular")) {
        spec = spec.and(BoardSpecification.recGreaterThan(30));
    } else {
        spec = spec.and(BoardSpecification.equalCategory(category));
    }
}
if(!searchType.isEmpty()) {
    if(searchType.equals("title")) {	
        spec = spec.and(BoardSpecification.searchTypeTitle(searchKeyword));
    } else {
        spec = spec.and(BoardSpecification.searchTypeWriter(searchKeyword));
    }
}

model.addAttribute("boards", boardRepository.findAll(spec, pageable));
  • 기존 코드보다 훨씬 깔끔하고 보기도 좋은 것 같았습니다.

💡 알게 된 점

  • JPA Specification을 사용하여 다중 조건 검색 구현
 

GitHub - Daegwon-Kim/SpringBoot-JPA-Blog

Contribute to Daegwon-Kim/SpringBoot-JPA-Blog development by creating an account on GitHub.

github.com

 

저작자표시 (새창열림)

'🚗 Backend Toy Project > 스프링 부트 게시판' 카테고리의 다른 글

[스프링부트 게시판] 36. 관리자 페이지 - 게시글 통계  (0) 2022.10.26
[스프링부트 게시판] 35. 관리자 페이지 - 회원 관리  (0) 2022.10.24
[스프링부트 게시판] 34. 사용자 프로필 이미지 추가  (0) 2022.09.27
[스프링부트 게시판] 33. 댓글 알림 기능  (1) 2022.09.23
[스프링부트 게시판] 32. 이전에 봤던 글 표시  (0) 2022.09.17
'🚗 Backend Toy Project/스프링 부트 게시판' 카테고리의 다른 글
  • [스프링부트 게시판] 36. 관리자 페이지 - 게시글 통계
  • [스프링부트 게시판] 35. 관리자 페이지 - 회원 관리
  • [스프링부트 게시판] 34. 사용자 프로필 이미지 추가
  • [스프링부트 게시판] 33. 댓글 알림 기능
Baeg-won
Baeg-won
  • Baeg-won
    좋았다면 추억이고 나빴다면 경험이다.
    Baeg-won
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 🍃 Spring, Spring Boot
        • 스프링 프레임워크 기초
        • 스프링 핵심 원리 - 기본편
        • 자바 ORM 표준 JPA 프로그래밍 - 기본편
        • 스프링 MVC
        • 실전! 스프링 부트와 JPA 활용1 - 웹 애플리..
      • 🥑 Web Technoloy
      • 🚗 Backend Toy Project
        • 스프링 부트 게시판
        • Photogram
        • Baeg-won Clothing Gallery
      • 🥇 Problem Solving
        • Breadth-First Search
        • Depth-First Search
        • Backtracking
        • Simulation
        • Two-pointer
        • Binary Search
        • Greedy
        • Dynamic Programming
        • Minimum Spanning Tree
        • Dijkstra
        • Floyd warshall
      • ☕ Java
        • 명품 자바 에센셜
        • Applications
      • 🍦 JavaScript
        • JavaScript 기초
      • 🐧 Linux
        • 이것이 리눅스다(CentOS 8)
      • 📟 Database
        • 혼자 공부하는 SQL
      • 🧬 Data Structure
      • 🎬 HTML
      • 🎤 Tech Interview
      • 📌 etc
        • Unity 2D Raising Jelly Game
        • C++
        • 영어 쉐도잉
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Baeg-won
[스프링부트 게시판] JPA Specification을 통해 쿼리 조건 다루기
상단으로

티스토리툴바