본문 바로가기
개발/JPA

[JPA] SELECT 하기(findBy , @Query , @Param , where , and , if test)

by 코딩하는 흰둥이 2024. 11. 10.

https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html#jpa.query.spel-expressions

 

JPA Query Methods :: Spring Data JPA

As of Spring Data JPA release 1.4, we support the usage of restricted SpEL template expressions in manually defined queries that are defined with @Query. Upon the query being run, these expressions are evaluated against a predefined set of variables. Sprin

docs.spring.io

공식문서를 항상 참고하자

 

 

JPA 의 SELECT 의 명명 규칙은

findBy ....

이다

 

JpaRepository 인터페이스를 상속받아서 사용할 수 있는 메서드는

모든 데이터를 조회하는 findAll()

PK 값으로 데이터를 조회하는 findById("pk컬럼")

이 있다

 

 

findAll() - 모든 데이터 조회
@Repository
public interface BoardRepository extends JpaRepository<BoardVo , Long> {
}

JpaRepository 를 상속받는다

 

@RestController
@RequestMapping("/api/*")
public class BoardController {

    @Autowired
    private BoardRepository boardRepository;
    
    @GetMapping("/findByAll")
    public void findByAll() throws Exception{
        // 모든 데이터 조회하기
        List<BoardVo> vo = boardRepository.findAll();

        System.err.println("findByAll : " + vo.toString());

    }
}

 

모든 데이터를 조회한다

 

 

 

findById() - PK 데이터 조회
@Repository
public interface BoardRepository extends JpaRepository<BoardVo , Long> {
}

JpaRepository 를 상속받는다

 

@RestController
@RequestMapping("/api/*")
public class BoardController {
    @Autowired
    private BoardRepository boardRepository;
    
    @GetMapping("/findById")
    public void findById() throws Exception{
        // ID 가 16번인 데이터 가져오기
        Optional<BoardVo> vo = boardRepository.findById(16L);

        System.err.println("findById : " + vo.get());

    }
}

 

PK 로 지정된 no 16을 조회한다

 

 

 

 

명명 규칙 where 절
@Repository
public interface BoardRepository extends JpaRepository<BoardVo , Long> {
    // 명명 규칙으로 title 을 찾아서 where 절로 조회한다
    List<BoardVo> findByTitle(String title) throws Exception;

}

JpaRepository 에 메서드를 생성한다

 

명명 규칙 findBy 과 찾으려는 컬럼 명을 메소드 명으로 한다

 

@RestController
@RequestMapping("/api/*")
public class BoardController {
    
    @Autowired
    private BoardRepository boardRepository;
    
    // JPA 명명 규칙으로 조회
    @GetMapping("/boardWhere")
    public List<BoardVo> boardWhere() throws Exception{
        List<BoardVo> vo = boardRepository.findByTitle("테스트");

        System.err.println("boardWhere : " + vo.toString());

        return vo;
    }
    
}

 

findByTitle 로 title 을 대상으로 조회한다

 

 

 

 

@Query 를 사용한 where 절
@Repository
public interface BoardRepository extends JpaRepository<BoardVo , Long> {

    // 사용자가 명한 메서드 명으로 파라미터 순번으로 where 절을 조회한다
    @Query("SELECT b FROM BoardVo b WHERE b.title = ?1")
    List<BoardVo> searchTitle(String title) throws Exception;


    // 특정 컬럼만 조회한다
    @Query("SELECT title FROM BoardVo  WHERE title = ?1")
    List<String> searchTitle(String title) throws Exception;
}

JpaRepository 에 메서드를 생성한다

@Query 어노테이션을 사용할 때는

메서드의 파라미터 입력 순으로

파라미터 순번을 넣어줘야 각각 매칭이 된다

WHERE title = ?1

 

 

@RestController
@RequestMapping("/api/*")
public class BoardController {
    
    @Autowired
    private BoardRepository boardRepository;
    
    // @Query 사용 조회
    @GetMapping("/searchTitle")
    public List<BoardVo> searchTitle() throws Exception{
        List<BoardVo> vo = boardRepository.searchTitle("테스트");

        System.err.println("searchTitle : " + vo.toString());

        return vo;
    }
    
    
    // @Query 사용 특정 컬럼 데이터만 조회
    @GetMapping("/searchTitle")
    public void searchTitle() throws Exception{
        List<String> vo = boardRepository.searchTitle("테스트");

        System.err.println("searchTitle : " + vo.toString());

    }
    
}

 

 

@Query 사용한 where 절

 

특정 컬럼 데이터만 조회

 

 

 

 

@Query + @Param 을 이용한 where 절
@Repository
public interface BoardRepository extends JpaRepository<BoardVo , Long> {

    // @Param 을 이용
    @Query("SELECT b FROM BoardVo b  WHERE b.title = :title")
    List<BoardVo> searchParmTitle1(@Param("title") String title) throws Exception;


    // @Param 을 이용
    // 특정 컬럼만 조회한다
    @Query("SELECT title FROM BoardVo  WHERE title = :title")
    List<String> searchParmTitle2(@Param("title") String title) throws Exception;
    
}

JpaRepository 에 메서드를 생성한다

@Param 을 이용하면 파라미터 순번이 필요 없고 

@Param 으로 지정한 명으로 where 절을 지정한다

오류나 잘못된 데이터를 조회를 방지할 수 있다

WHERE title = :title

 

 

@RestController
@RequestMapping("/api/*")
public class BoardController {

    @Autowired
    private BoardRepository boardRepository;

    @GetMapping("/searchParmTitle1")
    public void searchParmTitle1() throws Exception{
        // @Param 을 이용한 where 절 조회
        List<BoardVo> vo = boardRepository.searchParmTitle1("테스트");

        System.err.println("searchParmTitle2 : " + vo.toString());

    }


    @GetMapping("/searchParmTitle2")
    public void searchParmTitle2() throws Exception{
        // @Param 을 이용한 특정 컬럼 값만 조회
        List<String> vo = boardRepository.searchParmTitle2("테스트");

        System.err.println("searchParmTitle2 : " + vo.toString());

    }
    
}

 

 

 

명명 규칙, @Qeury 와 같은 where 절

 

 

특정 컬럼 데이터만 조회

 

 

 

 

@Query , @Param 을 이용한 where and 절
@Repository
public interface BoardRepository extends JpaRepository<BoardVo , Long> {

    // @Query 만 이용하여 where and 절 조회
    @Query("SELECT b FROM BoardVo b  WHERE b.title = ?1 AND b.writer = ?2")
    List<BoardVo> searchQueryTitle(String title , String writer) throws Exception;

    // @Param 을 이용하여 where and 절 조회
    @Query("SELECT b FROM BoardVo b  WHERE b.title = :title AND b.writer = :writer")
    List<BoardVo> searchParamTitle(@Param("title") String title , @Param("writer") String writer) throws Exception;
}

JpaRepository 에 메서드를 생성한다

@Query 만 이용할 경우 파라미터 순번을 정확하게 넣어준다

@Param 을 이용할 경우 어노테이션 명을 정확하게 넣어준다

 

 

@RestController
@RequestMapping("/api/*")
public class BoardController {

    @Autowired
    private BoardRepository boardRepository;
    
    
    @GetMapping("/searchQueryTitle")
    public void searchQueryTitle() throws Exception{
        // @Query 을 이용한 where and 절 조회
        List<BoardVo> vo = boardRepository.searchQueryTitle("테스트" , "yb");

        System.err.println("searchQueryTitle : " + vo.toString());

    }


    @GetMapping("/searchParamTitle")
    public void searchParamTitle() throws Exception{
        // @Param 을 이용한 where and 절 조회
        List<BoardVo> vo = boardRepository.searchParamTitle("테스트" , "yb");

        System.err.println("searchParamTitle : " + vo.toString());

    }

}

 

 

@Query 파라미터 순번을 맞춘 where and 절 조회

 

 

@Param 을 이용하여 파라미터 값을 지정한 where and 절 조회

 

 

 

if test 절 
@Repository
public interface BoardRepository extends JpaRepository<BoardVo , Long> {

    // if test 절 - searchOption 의 값에 따라 where 또는 and 절 변경
    @Query("SELECT a FROM BoardVo a WHERE" +
            "(:searchOption = 'title' AND a.title LIKE %:search%) OR " +
            "(:searchOption = 'writer' AND a.writer LIKE %:search% )" +
            "ORDER BY a.no DESC")
    List<BoardVo> search(@Param("searchOption") String searchOption , @Param("search") String search);

}

JpaRepository 에 메서드를 생성한다

예시로 검색단에서 제목, 작성자, 날짜 등으로 검색어를 조회할 때

조건에 따라 검색하는 if test 절이다

 

 

@RestController
@RequestMapping("/api/*")
public class BoardController {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private BoardRepository boardRepository;

    @GetMapping("/boardList")
    public List<BoardVo> boardList(@RequestParam String searchOption , @RequestParam String search) throws Exception{
        // if test 절 사용 - 검색 옵션에 따라 검색어 를 조회
        List<BoardVo> vo = boardRepository.search(searchOption, search);
        return vo;
    }
    
}

 

 

검색 옵션인 제목을 선택하고 검색할 검색어를 입력

 

 

쿼리가 실행

 

일치하는 데이터 조회

 

 

 


JPA 를 좋아하는 편은 아닌데

간단한 query 기준으로 프로젝트를 구성할 때

사용 방법이 익숙해지니 확실히 mybatis 를 이용해서

쓸 때 없이 Mapper.class 와 xml 을 만드는 거보다는 시간이 단축돼서 편하긴 했다

아마 join 을 이용할 때는 다시 빡치겠지...

 

댓글