일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 도커
- Workbench
- Git
- 자료구조
- 백준
- 참고X
- DP
- 5장
- c언어 제어문
- python기초
- 운체 1주차
- 그리디
- 파이썬 알고리즘 인터뷰
- #코린이 #코딩 #할 수 있다
- c언어
- 코딩테스트
- git오류
- python자료형
- 최단거리
- 인텔리제이
- 코테
- 스택
- c언어 기본
- python기본
- 4장
- 인스타
- git기초
- 데베시 1주차
- 1주차(1)
- git 오류
- Today
- Total
하루살이 개발자
[Spring JPA] Query Method 본문
Query Method
- JPA(Java Persistence API)란 자바에서 사용하고 있는 ORM의 표준으로 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑해주는 일을 한다.
- 스프링 데이터 JPA는 메소드 이름으로 쿼리 생성을 하는 쿼리 메소드 기능을 제공한다.
- 쿼리메서드는 메서드의 이름을 분석해서 JPQL쿼리를 실행한다!
- 쿼리 메서드를 활용하면 쉽게 쿼리문을 만들어 사용할 수 있다.
Query Method 사용
Query method는 JpaRepository를 상속하는 것 만으로도 Jpa의 method들을 사용할 수 있다.
JpaRepository<> 에서 괄호에는 첫번째에는 Jpa로 사용할 entity(class), 두번째는 해당 class의 pk타입이다.
public interface UserRepository extends JpaRepository<User, Integer>
Select Query
- 아래의 method들은 모두 select query의 일을 하는 method들이다.
- 이름은 find(get,ready,,,,) By가 핵심이며 두 문자 뒤에 구분할 수 있는 변수명을 넣어 구분하며 만들어주면 된다. 그러면 자동으로 Select Qeury Method가 만들어진다.
- 아래의 findBy, getBy, readBy, queryBy, searchBy, streamBy, find (Entity 명) By 는 모두 Select의 일을 하는 keyword이며 개발자는 이중에서 자신이 가독성이 높다고 생각되는 것을 이용하면 된다.
User findByEmail(String email);
User getByEmail(String email);
User readByEmail(String email);
User queryByEmail(String email);
User searchByEmail(String email);
User streamByEmail(String email);
User findUserByEmail(String email);
* Return type은 List, Set, Object등의 여러 타입으로 할 수 있으며 JPA가 데이터를 읽어오고 return type에 맞춰서 데이터를 return해준다.
단 데이터가 여러개인데 User와 같이 단일 객체로 return하면 오류가 발생한다.
First, Top
- First, Top은 둘 다 데이터에서 출력할 데이터의 수를 정해서 리턴하게 하는 keyword이다.
- 기본적으로 keyword뒤에 숫자를 붙이지 않으면 가장 상위 데이터 하나가 리턴되며(Default = 1) 이름 뒤에 출력할 데이터의 수를 붙이면 해당 수만큼 리턴한다.
List<User> findFirst1ByName(String name); // 상위 1개의 데이터 return
List<User> findTop2ByName(String name); // 상위 2개의 데이터 return
List<User> findLast1ByName(String name); // Last filter는 없다
And, Or
Query문에서 and, or을 사용하고 싶은 경우 method안에 And or을 넣어준다
List<User> findByNameAndEmail(String name, String email);
List<User> findByNameOrEmail(String name, String email);
After, Before, GreaterThan, LessThan, Between
- After, Before, GreaterThan, LessThan은 값 비교를 해주는 keyword이다.
After, GreaterThan은 특정 날짜/값 이후(또는 큰것)에 발생한 것을 조회하게 해주는 keyword이다.
Before, LessThan은 특정 날짜/값 이전(또는 작은것)을 조회하게 해주는 keyword이다. - After, GreaterThan과 Before, LessThan은 서로 같은 기능을 하는 필터지만 가독성을 위해 After, Before은 날짜에만 사용하는 것을 추천한다.
- 또한 조건을 걸다보면 초과, 미만 뿐만 아니라 이상, 이하의 조건도 필요할 것이다. 그럴 경우에는 GreaterThanEqual과 같이 Equal을 붙여주면 된다.
- ~이상 ~이하의 의미를 갖는 Between keyword도 존재한다. Between은 parameter를 2개를 받으며 Between은 위의 After, Before, GreaterThan, LessThan과 다르게 해당 값들도 포함한다.(이상, 이하를 의미한다.)
List<User> findByCreatedAtAfter (LocalDateTime lastDay);
// CreatedAt이 lastDay이후인 데이터들 return (yesterDay미포함)
List<User> findByIdAfter(Long id);
// input id보다 큰 id를 가진 데이터들을 return (id 미포함)
List<User> findByCreatedAtGreaterThan (LocalDateTime yesterday);
// CreatedAt이 lastDay이후인 데이터들 return (yesterDay미포함)
List<User> findByCreatedAtGreaterThanEqual (LocalDateTime yesterday);
// CreatedAt이 lastDay이후인 데이터들 return (yesterDay포함)
List<User> findByCreatedAtBetween(LocalDateTime yesterday, LocalDateTime tomorrow);
// CreatedAt이 lastDay와 tomorrow사이 값인 데이터들 return (yesterDay, tomorrow포함)
List<User> findByIdBetween(Long id1, Long id2);
// id가 id1이상, id2이하인 데이터들 return
* After, Before, GreaterThan, LessThan은 초과 미만을 의미하며 Between은 이상, 이하를 의미하는 것을 헷갈리면 안된다!!!
is(Not)Empty, is(Not)Null
- isNull은 해당 값에 Null값이 있는지 체크하는 keyword이다.
- NotEmpty는 String과 같은 문자열이 비어있는지 체크가 아닌 Collection type의 변수가 not empty(비어있는지)를 체크한다.
List<User> findByIdIsNotNull(); // Id값에 Null값이 없는지?
List<User> findByAddressIsNotEmpty();
In
- In절은 query문에서 in절이기 때문에 parameter로 iterater type인 list가 들어가게 된다. generic type이 들어가야하는 <>에는 검색하는 column의 data type을 넣는다.
- 일반적으로 in절은 다른 query의 결과값을 다시 query에 넣어야 할 때 사용한다!
- in절을 사용할 때는 과부하 걸리는 것을 예방하기 위해서 다른 query문의 결과로 얼마나 많은 데이터들이 나올지 사전에 검토를 하고 사용하는게 좋다.
List<User> findByNameIn(List<String> name);
StartingWith/EndingWith/Contains
- 해당 keyword들은 문자열에 사용하며 해당 문자열로 시작하는지, 끝나는지, 포함하는지를 filtering할 때 사용한다.
- contains("rti")와 like("%rti%")는 같은 것이다
List<User> findByNameStartingWith(String name);
List<User> findByNameEndingWith(String name);
List<User> findByNameContains(String name);
List<User> findByNameLike(String name);
Is, Equals
- Is는 해당 값을 가진 data를 찾는 keyword로 Is, Equals, 또는 아무런 키워드를 넣지 않으면 Is로 보게된다.
- 아래 3개의 method는 모두 parameter의 name과 동등한 이름의 데이터들을 출력하는 method이다.
Set<User> findUserByNameIs(String name);
Set<User> findUserByName(String name);
Set<User> findUserByNameEquals(String name);
Sorting
- Sorting은 조건에 따라 데이터의 정렬을 해주는 Keyword이다.
- Desc/ Asc로 정렬한다.
- 여러개의 조건으로 find하는 경우는 And를 사용하였으나 정렬 조건으로 여러개의 값을 사용하는 경우는 And를 사용하지 않고 조건을 이어서 붙인다.
- Sort method를 사용하여 정렬시킬 수도 있다.
List<User> findTop1ByNameOrderByIdDesc(String name);
// Id로 내림차순으로 정렬 후 입력 name과 같은 것의 맨 위의 있는 값을 뽑아온다.
List<User> findFirst2ByNameOrderByIdDescEmailAsc(String name);
// 여러개의 조건으로 find하는 경우는 And를 사용하였으나 정렬 조건으로 여러개의 값을 사용하는 경우는 And를 사용하지 않고 조건을 이어서 붙인다.
List<User> findFirstByName(String name, Sort sort);
* Sort Parameter를 사용하여 정렬하는 경우
- Sort Parameter를 사용하지 않는 방법으로 Sorting을 하면 조건이 많아질수록 메소드의 이름 길이도 길어지며 코드의 가독성에도 그리 좋지 않다.
- 또한 조건에 따라 여러 method를 만들어야하는데 Sort method를 사용할 경우 하나의 method로 여러 sort조건을 줘서 사용할 수 있다. 그래서 아래와 같이 Sorting Method를 사용하는 것을 추천한다.
- 하지만 반대로 같은 Sorting방식으로 사용되는 경우가 많은 경우 위의 Keyword를 사용한 method를 사용하는게 가독성 측면에서 더 좋을 수 있다.
- 개발자는 같은 결과를 내더라도 여러 코딩 방식이 있다는 것을 인지하고 어떤 것이 가독성이 더 좋을지 생각하며 코딩해야한다.
쿼리 메서드 필터 조건
KeywordSampleJPQL snippet
Distinct | findDistinctByLastnameAndFirstname | select distinct … where x.lastname = ?1 and x.firstname = ?2 |
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is, Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull, Null | findByAge(Is)Null | … where x.age is null |
IsNotNull, NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection ages) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstname) = UPPER(?1) |
Reference
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
'Backend > Spring' 카테고리의 다른 글
[Spring] DB 연동 (0) | 2022.05.10 |
---|---|
[SpringBoot] @Valid 어노테이션으로 Parameter 검증 (0) | 2022.02.15 |
intelliJ(인텔리제이) 단축키 (MAC 기준) (0) | 2022.02.14 |