Query Methods
Query Methods
- Spring Data JPA의 쿼리를 생성하는 기능으로, 메소드명을 규칙에 맞게 작성하면 자동으로 쿼리가 생성
- 복잡한 Entity나 Join 상황에서는 활용이 어렵다
샘플 예제
User Entity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Entity
@Getter
@Setter
public class User{
@Id
private Long id;
@Column(name = "FirstName")
private String firstName;
@Column(name = "Last_Name")
private String lastName;
private int age;
private LocalDateTime startDate;
private boolean active;
}
- 쿼리 메소드를 사용 시 변수명을 기준으로 작성이 된다
- 첫글자가 대문자는 불가능하고, 중간에 언더바(“_”) 같은 기호도 인식이 불가능하다.
- DB 테이블에서 칼럼명과 매핑 시키기 위해 @Column의 속성을 사용하면 된다. @Column(name = “Last_Name”)
User Repository
- 대문자로 키워드 분리하여 자동으로 인식한다
- 따라서 대소문자에 유의하여 작성하여야 한다.
- 또한 매개변수명은 어떤 것을 해도 순서대로 들어오지만, 명확한 코드를 위해 칼럼명으로 작성을 하는게 좋다
1
2
3
4
5
6
7
8
9
@Repository
public instance UserRepository extends JpaRepository<User, Long> {
List<User> findFirst5ByLastnameAndFirstnameOrderByIdDesc(String lastName, String firstName);
Boolean existsByStartDateLessThanEqual(LocalDateTime startDate);
long countByFirstnameIgnoreCaseLike(String firstName);
}
- 첫번째 메소드는 lastname과 firstname이 입력받은 값과 일치하는 user들을 id 역순으로 정렬하여 5개 데이터만 가져온다
- 서비스에서 return 값으로
- userRepository.findFirst5ByLastnameAndFirstnameOrderByIdDesc(“KillDong”, “Hong”);
- 실제 수행된 쿼리
1
2
3
4
5
select *
from user
where last_name = ?
and first_name = ?
order by id desc limit 5
- 두번째 메소드는 입력받은 날짜보다 startDate가 적거나 같은(<=) 데이터가 있다면 true를 없다면 false를 리턴하는 메소드이다
userRepository.existsByStartDateLessThanEqual(LocalDateTime.now());
- 세번째는 대소문자를 무시하고 Like 쿼리를 날려서 해당되는 데이터의 수를 가져오는 메소드이다.
- 입력변수에 “%”를 붙여 원하는 위치에 포함하여 실행한다
- userRepository.countByFirstnameIgnoreCaseLike(“kim%”);
쿼리 Subject 키워드
- 메소드 처음 시작 위치에 오는 키워드로 어떤 작업을 할 것이며, 어떤 데이터 타입을 리턴할지 결정한다.
- findBy : List
와 같이 Collection 타입으로 리턴되나, 조회하는 대상이 Primary Key라면 아래와 같이 단일 객체로 리턴된다 - Optional
user = userRepository.findById((long)1);
- Optional
- findFirst(숫자)By : findFirstBy..과 같이 숫자가 없다면 제일 첫번째 데이터 1개가 리턴되고, 숫자가 있다면 Collection 타입으로 리턴된다.
- existBy : boolean 타입으로 리턴
- countBy : int/long 등으로 해당되는 데이터 수 리턴
- deleteBy : void 타입 혹은 int/long 등으로 삭제된 데이터 수 리턴
메소드명 내 키워드
- 메소드명 By 뒤에 작성되는 키워드로 SQL의 Where절 내 명령어와 같은 역할이다
키워드 | 샘플 | JPQL | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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.lastanem = ?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 is not null | ||||||||||||
Like | findByFristnameLike | ..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..where x.age in ?1 | NotIn | findByAgeNotIn(Collection | ..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) | |