일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 오라클 아키텍처
- 봄 사랑 벚꽃 말고
- 스위트라떼
- 아이유
- 슬픔의 후에
- 레이디스코드
- 핑거스타일
- SQL 처리
- DBMS
- 기타
- Inside Of Me
- 악보
- 니가 참 좋아
- 천공의 시간
- 인덱스
- 6학년 8반 1분단
- 장범준
- 러블리즈
- nginx
- 데이터베이스
- db
- 개발자
- 신입
- oracle
- 말 더듬
- 오라클
- IT
- index
- I'm fine thank you
- DBMS 구성요소
취미로 음악을 하는 개발자
[Spring Framework] 쿼리 메소드 (1) 본문
JPA에서는 각 데이터베이스에 맞는 Dialect가 별도의 SQL에 대한 처리를 자동으로 처리해 주기 때문에 개발시 생산성을 향상시킬 수 있다. 반면, 조금 복잡한 쿼리를 작성하기 위해서는 데이터베이스를 대상으로 하는 SQL이 아니라 JPA에서 사용하는 것(Named Query, JPQL, Query dsl 등)을 알아야 한다.
Spring Data JPA는 이러한 번거로운 과정을 조금이라도 줄여줄 수 있는데 그 방법 중 하나가 쿼리 메소드이다.
쿼리 메소드는 메소드의 이름만으로 필요한 쿼리를 만들어 내는 기능으로, 네이밍 룰만 알고 있어도 사용할 수 있다.
프로젝트 생성
* 이전 'boot02' 프로젝트의 main 파일들을 그대로 가져오면 된다.
Spring Web, MySQL, lombok, JPA, Devtools
: Tomcat이 실행된 상태에서 코드를 수정하면 자동으로 재시작하는 기능
// application.properties
1 2 3 4 5 6 7 8 9 10 11 12 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/jpa_ex?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.username=user spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update spring.jpa.generate-ddl=false spring.jpa.show-sql=true spring.jpa.database=mysql spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect logging.level.org.hibernate=info | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package org.zerock; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.zerock.domain.Board; import org.zerock.persistence.BoardRepository; @RunWith(SpringRunner.class) @SpringBootTest public class Boot03ApplicationTests { @Autowired private BoardRepository repo; @Test public void testInsert200() { for (int i = 1; i <= 200; i++) { Board board = new Board(); board.setTitle("제목.." + i); board.setContent("내용 ..." + i + " 채우기 "); board.setWriter("user0" + (i%10)); repo.save(board); } } } | cs |
BoardRepository 인터페이스를 작성하고 test 클래스에 위의 더미 데이터를 생성하는 코드를 넣고 실행해준다.
쿼리 메소드
: Spring Data JPA에서 제공하는 것으로, 메소드의 이름만으로 원하는 질의를 실행할 수 있다. 단 여기서 쿼리라는 용어는 'select'에만 해당한다. 쿼리 메소드는 다음과 같은 단어들로 시작한다.
find..By.. read..By query..By get..By count..By
예를 들어, find..By로 쿼리 메소드를 만든다면 find 뒤에 엔티티 타입을 지정한다. Board 클래스라면 findBoardBy.. 가 된다.
만일 중간에 엔티티 타입을 지정하지 않는다면 현재 실행하는 Repository의 타입 정보를 기준으로 동작한다.
By 뒤쪽에는 컬럼명을 이용해서 구성한다. 예를 들어, 제목으로 검색하고자 한다면 findBoardByTitle이 된다.
쿼리 메소드 리턴 타입은 Page<T>, Slice<T>, List<T>와 같은 Collection <T> 형태가 될 수 있다. 가장 많이 사용되는 것은 List<T>, Page<T> 타입을 이용하는 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package org.zerock.persistence; import java.util.Collection; import java.util.List; import org.springframework.data.repository.CrudRepository; import org.zerock.domain.Board; public interface BoardRepository extends CrudRepository<Board, Long>{ public List<Board> findBoardByTitle(String title); public Collection<Board> findByWriter(String writer); // 작성자에 대한 Like % 키워드 % public Collection<Board> findByWriterContaining(String writer); // Or 조건의 처리 public Collection<Board> findByTitleContainingOrContentContaining( String title, String content); // Title Like % ? % and Bno > ? public Collection<Board> findByTitleContainingAndBnoGreaterThan( String keyword, Long num); // Bno > ? Order by bno Desc public Collection<Board> findByBnoGreaterThanOrderByBnoDesc(Long bno); } | cs |
테스트 코드에서 사용해볼 쿼리 메소드를 미리 다 작성해놨다. 테스트 코드만 하나씩 살펴보면서 풀이할 것이다.
다음 코드를 테스트 클래스에 넣어준다.
1 2 3 4 5 6 7 8 9 10 11 | @Test public void testByTitle() { // before Java 8 // List<Board> list = repo.findBoardByTitle("제목..177"); // for (int i = 0, len = list.getBatchSize(); i < len; i++) { // System.out.println(list.get(i)); // } // Java 8 repo.findBoardByTitle("제목..177").forEach(board -> System.out.println(board)); } | cs |
testByTitle()을 실행하면 다음과 같은 출력이 나온다.
Board 클래스가 가리키는 테이블에서 제목 이름이 '제목..177'인 컬럼을 찾아 출력한 것이다.
코드를 보면 Java 8 이전의 코드와 이후의 코드가 나와있는데 8 버전부터 forEach문 한 줄로 처리할 수 있는 것 같다. (forEach, 람다식)
아래의 표는 Spring Data JPA 문서에 나와있는 쿼리 메소드 목록을 가져온 것이다.
Keyword | Sample | JPQL snippet |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
'공대인 > Spring[Boot]' 카테고리의 다른 글
[Spring Framework] 쿼리 메소드 (3) (0) | 2019.10.06 |
---|---|
[Spring Framework] 쿼리 메소드 (2) (0) | 2019.10.05 |
[Spring Framework] Spring Data JPA Repository 테스트 (0) | 2019.10.01 |
[Spring Framework] Spring Data JPA Repository (0) | 2019.09.29 |
[Spring Framework] Spring Data JPA 엔티티 클래스 (Entity Class) (0) | 2019.09.29 |