JPA/스프링 데이터 JPA
-
Web 확장 - 페이징과 정렬JPA/스프링 데이터 JPA 2023. 8. 12. 15:32
페이징과 정렬을 Web에서 편하게 사용할 수 있도록 스프링 데이터 JPA가 기능을 지원한다. @GetMapping("/members") public Page list(Pageable pageable) { Page page = memberRepository.findAll(pageable); return page; } @PostConstruct public void init() { for (int i = 0; i < 100; i++) { memberRepository.save(new Member("user" + i, i)); } } memberRepository의 findAll의 파라미터에 pageable을 넣어주면 페이징을 사용할 수 있다. url에 파라미터로 페이지와 사이즈를 넘겨주면 웹에서 페이징을 해..
-
Auditing - 엔티티의 생성 변경 기록JPA/스프링 데이터 JPA 2023. 8. 12. 14:57
엔티티를 생성과 변경을 할 때 변경을 한 사람, 시간 기록을 남겨두면 운영 과정에서 훨씬 도움이 될 것이다. 순수 JPA에서의 Auditing 1. JpaBaseEntity라는 날짜 속성을 알려주는 엔티티를 만든다. @Getter @MappedSuperclass // 진짜 상속은 아니고 선언된 속성들만 사용한다는 것 public class JpaBaseEntity { @Column(updatable = false) private LocalDateTime createdDate; private LocalDateTime updatedDate; @PrePersist public void prePersist() { LocalDateTime now = LocalDateTime.now(); createdDate = ..
-
스프링 데이터 JPA에서의 사용자 정의 리포지토리JPA/스프링 데이터 JPA 2023. 8. 12. 14:20
스프링 데이터 JPA 리포지토리는 인터페이스만 정의하고 구현체는 스프링이 자동으로 생성해주는데 스프링 데이터 JPA가 제공해주는 인터페이스를 직접 구현하려면 구현해야할 것들이 너무 많다. 따라서 별도로 인터페이스를 만들어서 기능을 구현한 다음 그 인터페이스를 repository에서 상속받는 방법이 있다. 1. MemberRepositoryCustom을 만들어서 메서드를 선언만 한다. public interface MemberRepositoryCustom { List findMemberCustom(); } 2. 선언한 인터페이스를 구현해서 JPQL을 작성한다. 이 때 이름은 repository 이름 + Impl로 맞춰야 한다. @RequiredArgsConstructor public class Member..
-
JPA HintJPA/스프링 데이터 JPA 2023. 8. 12. 00:19
JPA 쿼리 힌트 (SQL 힌트가 아니라 JPA 구현체에게 제공하는 힌트) JPA에서 데이터를 변경할 때 변경 감지라는 기능을 사용해서 트랜잭션 안에서 데이터를 변경한다. 이 때 스냅샷을 생성하기도 하고 변경을 위해서 메모리를 소비한다. 그런데 진짜 조회만 할 때에는 이런 것들이 필요없으니 최적화를 해줘야한다. public interface MemberRepository extends JpaRepository { @QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true")) Member findReadByUsername(String username); // 조회만 할 때 조회만 해서 쿼리를 최적화 해주는 작업 } @Quer..
-
@EntityGraph - 어노테이션으로 fetch joinJPA/스프링 데이터 JPA 2023. 8. 12. 00:04
JPA 사용 시 N + 1 문제를 해결해주는 기능이다. N + 1 문제를 해결하기 위해 fetch join이 중요하다는 것은 여러번 강조했었다. @EntityGraph는 쉽게 말해 fetch join을 쉽게 해주는 기능이다. 스프링 데이터 JPA는 쿼리를 최소한으로 작성하는데 fetch join을 하기 위해서는 무조건 JPQL을 작성해야하기 때문에 메서드 이름과 어노테이션으로 fetch join 최적화를 하기 위한 기능이 @EntityGraph이다. public interface MemberRepository extends JpaRepository { @Override // findAll()은 상속받은 상위 인터페이스에 있으므로 오버라이드 @EntityGraph(attributePaths = {"team..
-
벌크성 수정 쿼리JPA/스프링 데이터 JPA 2023. 8. 11. 23:21
데이터 하나를 수정할 때에는 변경 감지가 좋지만 모든 데이터를 수정할 때, 예를 들어 모든 상품의 가격을 10% 인상을 할 때에는 벌크 연산이 좋다. @Modifying // JPA에서 query.executeUpdate()과 같은 기능 @Query("update Member m set m.age = m.age + 1 where m.age >= :age") int bulkAgePlus(@Param("age") int age); 스프링 데이터 JPA에서는 @Modifying을 넣어준 다음 update 쿼리를 날려주면 된다. 반환은 update 되는 데이터의 개수이므로 int로 반환해주면 된다. @Modifying을 넣어주지 않으면 에러가 난다. @Test public void bulkUpdate() thr..
-
스프링 데이터 JPA의 페이징과 정렬JPA/스프링 데이터 JPA 2023. 8. 11. 23:00
페이징과 정렬 파라미터 'org.springframework.data.domain.Sort' : 정렬 기능 'org.springframework.data.domain.Pageable' : 페이징 기능 (내부에 'Sort' 포함) data.jpa가 아니라 data.domain이다. 즉, 어떤 SQL 언어를 사용하든 간에 정렬 방법은 같다는 것이다. 특별한 반환 타입 'org.springframework.data.domain.Page' : 추가 count 쿼리 결과를 포함하는 페이징 (totalCount 포함) 'org.springframework.data.domain.Slice' : 추가 count 쿼리 없이 다음 페이지만 확인 가능 'List' : 추가 count 쿼리 없이 결과만 반환 Page publ..
-
@Query - 쿼리 정의하기JPA/스프링 데이터 JPA 2023. 8. 11. 21:20
public interface MemberRepository extends JpaRepository { @Query("select m from Member m where m.username = :username and m.age = :age") List findUser(@Param("username") String username, @Param("age") int age); } Repository에 @Query 어노테이션으로 쿼리를 정의해서 사용할 수 있다. 이러한 방식의 장점은 첫 번째로 findByUsernameAndAgeGreaterThan() 같이 메서드 이름으로 자동으로 쿼리를 날려주는 방식은 2가지 조건만으로도 메서드명이 길어지는데 위의 방식은 그렇지 않고, 내가 보내고싶은 쿼리를 명확하게 알..