[JPA] Select Query 사용 방법

SpringData JPA를 사용하여 웹 프로젝트를 진행하면서 Select Query를 작성 시 잊어버리게 되어 검색을 하게 되는데 자주 사용하는 내용들을 정리하였습니다. JpaRepository를 상속받아 사용하는 기본 Query와 @Query 주석을 사용하여 JPQL 및 네이티브 SQL 쿼리를 실행하는 방법에 대해 알아보겠습니다.

Entity

먼저 데이터베이스에 저장하기 위해 tb_user 테이블 이름의 Entity 클래스를 작성합니다.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@Entity
@Table(name = "tb_user")
@Data
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected long id;

/** 사용자ID */
@Column(nullable = false, length = 45)
private String userId;

/** 사용자명 */
@Column(nullable = false, length = 100)
private String name;

/** 사용자비밀번호 */
@Column(nullable = false, length = 100)
private String password;

/** 이메일 */
@Column(length = 45)
private String email;

/** 연락처 */
@Column(length = 20)
private String tel;

/** 생성일시 */
@CreationTimestamp
private LocalDateTime createDate;

/** 수정일시 */
@UpdateTimestamp
private LocalDateTime updateDate;

/** 권한 */
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private UserRole role;

public enum UserRole {
ADMIN, GUEST
}
}

Repository

Entity 클래스를 작성했다면 이번엔 Repository 인터페이스를 만들어야 합니다.
Entity의 기본적인 CRUD가 가능하도록 JpaRepository 인터페이스를 제공합니다.

1
2
public interface UserRepository extends JpaRepository<User, Long> {
}

기본 Query

Spring Data JPA에서 기본적으로 제공하는 Query는 규칙에 맞게 작성해야 합니다.

Method 설명
findBy… 쿼리를 요청
countBy… 쿼리 결과 행 수를 요청
orderBy… 쿼리 결과를 정렬
existsBy… 해당 조건의 항목이 존재하는지 확인

그리고 Query 메소드에 포함할 수 있는 키워드가 있습니다. 아래 참고 사이트에 자세하게 더 다양하게 정리가 되어있습니다.

Keyword 설명
And 여러 컬럼을 and 로 쿼리
Or 여러 컬럼을 or 로 쿼리
Containing like 쿼리
Like like 쿼리
Between 컬럼의 두 값 사이에 있는 항목 쿼리
OrderBy 쿼리 결과를 정렬
In 여러 값 중에 하나인 항목 쿼리
Exists 해당 조건의 항목이 존재하는지 확인

아래는 예제 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
User findByUserId(String userId);
User findByUserIdAndPassword(String userId, String password);

List<User> OrderByName();
List<User> OrderByCreateDateDesc();
List<User> findByRoleOrderByCreateDateDesc(Role role);

List<User> findByNameContaining(String name);
List<User> findByCreateDateBetween(LocalDateTime startDate, LocalDateTime endDate);

boolean existsByUserId(String userId);

int countByRole(Role role);

JPQL(Java Persistence Query Language)

JPQL은 SQL과 비슷한 문법을 가진 객체 지향 쿼리입니다.

JPQL과 Native SQL 동일하게 @Query 어노테이션을 사용하여 쿼리를 작성하고, 또한 두 가지 방법으로 쿼리에 메소드의 매개변수 값을 전달할 수 있습니다.

  1. @Param 어노테이션을 사용하여 이름으로 정의 된 매개변수를 쿼리에 전달합니다.
  2. 메소드의 매개변수 순서로 쿼리에 전달합니다.(1부터 시작)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Query(value = "SELECT u FROM User u WHERE u.role = 'GUEST'")
List<User> findByRole();

@Query("SELECT u FROM User u WHERE u.userId = :userId")
User findByUserId(@Param("userId") String userId);

@Query("SELECT u FROM User u WHERE u.userId = :userId and u.password = :password")
User findByUserIdAndPassword(@Param("userId") String userId, @Param("password") String password);

@Query("SELECT u FROM User u WHERE u.userId = ?1")
User findByUserId(String userId);

@Query("SELECT u FROM User u WHERE u.userId = ?1 and u.password = ?2")
User findByUserIdAndPassword(String userId, String password);

Native SQL

네이티브 SQL을 사용하여 쿼리를 정의할 수 있습니다. 네이티브 SQL을 사용하려면 nativeQuery 속성의 값을 true 로 설정합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Query(value = "SELECT * FROM tb_user u WHERE u.role = 'GUEST'", nativeQuery = true)
List<User> findByRole();

@Query("SELECT * FROM tb_user u WHERE u.userId = :userId", nativeQuery = true)
User findByUserId(@Param("userId") String userId);

@Query("SELECT * FROM tb_user u WHERE u.userId = :userId and u.password = :password", nativeQuery = true)
User findByUserIdAndPassword(@Param("userId") String userId, @Param("password") String password);

@Query("SELECT * FROM tb_user u WHERE u.userId = ?1", nativeQuery = true)
User findByUserId(String userId);

@Query("SELECT * FROM tb_user u WHERE u.userId = ?1 and u.password = ?2", nativeQuery = true)
User findByUserIdAndPassword(String userId, String password);

참고

Share