개발/Spring

[Spring]Spring Data JPA

grulsuitg 2022. 7. 10. 21:46

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
															(010new Sort(Direction.DESC, "name"));
														//현재 페이지, 조회 데이터 수, 정렬 정보

Pageble의 구현체로 PageRequest 를 사용.

사용자 정의 리포지토리 구현

QueryDsl 을 이용 혹은 인터페이스의 메서드를 직접 구현하고 싶다면 다음과 같은 절차를 따르면 됩니다.

  1. 사용자 정의 인터페이스 만들기
  2. interface CustomizedUserRepository { void someCustomMethod(User user); }
  3. 인터페이스 구현하기이름 : 사용자정의인터페이스 + Impl → Spring Data 에서 인식해서 Spring bean으로 인식해서 등록하여 줍니다. Postfix는 설정을 통해 변경 가능
  4. class CustomizedUserRepositoryImpl implements CustomizedUserRepository { public void someCustomMethod(User user) { // Your custom implementation } }
  5. 사용자 정의 인터페이스 상속여러 사용자 정의 인터페이스를 상속하는 것도 가능합니다.
  6. interface UserRepository extends CrudRepository<User, Long>, CustomizedUserRepository { // Declare query methods here }

ETC.

@PrePsersist

새로운 엔티티에 대해 persist가 호출되기 전 수행되는 함수.

@PreUpdate

엔티티가 변경감지 혹은 병합으로 업데이트 되기 전

@Modifying

값을 변경하는 쿼리(update, delete, insert)에 붙여줘야 동작. Spring Data JPA가 생성해주는 메소드에는 붙여줄 필요 X → @Query 가 있는 메소드에 붙어주어야 합니다.

Reference