“Spring Data JPA란 무엇일까?”
안녕하세요 Spring framework에서 JPA를 보다 편리하게 사용할수 있도록 도와주는 Spring Data JPA를 소개해보려고 합니다.
Spring Data JPA란?
JPA를 보다 쉽게 사용할 수있도록 지원해주는 Framewrok
→ data access layer를 구현하기 위한 boilerplate code 를 줄이는 것이 목표입니다.
How to?
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S entity);
Optional<T> findById(ID primaryKey);
Iterable<T> findAll();
void delete(T entity);
// … more functionality omitted.
}
특징
-
Interface 로 Repository 구현.
-
Repository <T, ID>
T : 저장할 Entity
ID : entity 의 primary key -
CRUD save : entitiy 저장
findById : id(pk) 로 entity 조회
findAll : 모든 entity 조회
delete : Entity 삭제
Update 는 변경감지로 이루어집니다.
메소드 이름으로 쿼리 생성
find…By
[condition], read…By
[condition], delete…By
[condition] 등과 같이 method를 만들면 자동으로 쿼리가 생성됩니다.
interface PersonRepository extends Repository<Person, Long> {
List<Person> findByLastname(String lastname);
/*
-> 다음과 같은 JPQL이 만들어집니다.
"select p from Person p where p.Lastname= :lastname"
-> 다음과 같은 SQL이 만들어집니다.
"SELECT *
FROM person
WHERE person.lastname = ?"
*/
}
…
에는 알기 쉽도록 이름을 넣어주면 되고 [condition]에는 원하는 조건을 넣어주면 됩니다.
Docs : https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords
@Query 를 이용한 쿼리 정의
메소드에 JPQL 쿼리를 작성 가능합니다.
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}
JPA 만 이용하면 메소드에 @Query 어노테이션을 붙이는 것이 불가능하지만
Spring Data JPA 는 메소드에 직접 @Query 어노테이션을 붙여 Named Query
가 가능하게 해주어 직관적으로 이해할 수 있도록 도와줍니다.
페이징과 정렬
Pageble 과 Sort class 를 이용해 처리가 가능합니다.
Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);
Page : 추가 count 쿼리 결과를 포함하는 페이징
Slice : 추가 count 쿼리 없이 다음 페이지만 확인
PageRequest pageRequest = new PageRequest(0, 10, new Sort(Direction.DESC, "name"));
//현재 페이지, 조회 데이터 수, 정렬 정보
Pageble의 구현체로 PageRequest
를 사용.
사용자 정의 리포지토리 구현
QueryDsl을 이용 혹은 인터페이스의 메서드를 직접 구현하고 싶다면 다음과 같은 절차를 따르면 됩니다.
- 사용자 정의 인터페이스 만들기
interface CustomizedUserRepository { void someCustomMethod(User user); }
- 인터페이스 구현하기
class CustomizedUserRepositoryImpl implements CustomizedUserRepository { public void someCustomMethod(User user) { // Your custom implementation } }
이름 : 사용자정의인터페이스 + Impl
→ Spring Data 에서 인식해서 Spring bean으로 인식해서 등록하여 줍니다.
Postfix는 설정을 통해 변경 가능 - 사용자 정의 인터페이스 상속
interface UserRepository extends CrudRepository<User, Long>, CustomizedUserRepository { // Declare query methods here }
여러 사용자 정의 인터페이스를 상속하는 것도 가능합니다.
ETC.
@PrePsersist
새로운 엔티티에 대해 persist가 호출되기 전 수행되는 함수.
@PreUpdate
엔티티가 변경감지 혹은 병합으로 업데이트 되기 전 동작
@Modifying
값을 변경하는 쿼리(update, delete, insert)에 붙여줘야 동작.
Spring Data JPA가 생성해주는 메소드에는 붙여줄 필요 X
→ @Query 가 있는 메소드에 붙어주어야 합니다.
마치며
복잡한 SQL과 설정, 단순한 CRUD 생성을 획기적으로 줄여주는 Spring Data JPA를 이용해보시는 건 어떨까요?