본문 바로가기

JPA

패스트캠퍼스 챌린지 5일차 - JpaRepository, @Query

📌 JpaRepository

✔️ findById 와 getOne의 차이

  • findById는 Eager전략을 사용한다.
    • em.find() 를 통해 실제 엔티티를 바로 조회한다.
  • getOne은 Lazy전략을 사용한다.
    • em.getReference() 를 통해 프록시 객체를 조회해서 반환한다.
      이후 실제 사용시 세션을 초기화해서 값을 얻어온다.

✔️ existsById

  • id를 조건으로하는 count 집계쿼리를 이용해서 유무를 확인한다.
    • count 집계쿼리의 결과가 1 이상이라면 해당 id를 PK로 하는 row가 존재하는 것
  • id로 엔티티를 가져와서 유무를 확인하는 것이 아니다.

✔️ deleteAll

  • 삭제하고자 하는 row만큼의 select 쿼리가 나간 후 각 row마다 delete 쿼리를 날린다.
  • 내부적으로 findAll 호출한다.
    • findAll로 얻은 객체를 for 문을 돌며 하나씩 delete 한다.

✔️ deleteInBatch

  • 삭제하고자 하는 row를 in 쿼리를 이용해 한 번에 조회한다.
  • select * from entity where id in (1,2,3,4...)
  • 조회된 row에 대해 or 조건으로 한 번의 delete문 수행한다.
  • delete from entity where id=? or id=?

✔️ Paging

Page<Entity> entity = repository.findAll(PageRequest.of(n, m)); 

Page 메서드

  • getTotalElements()
  • getTotalPages()
  • getNumberOfElements()
  • getSort()
  • getSize()

✔️ QueryByExample (ExampleMatcher)

ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnorePaths("무시할 필드명")
            .withMatcher("적용할 필드명", endsWith());
Example<User> example = Example.of(new User("name", "asd@naver.com"), matcher)            
userRepository.findAll(example);
  • .withIgnorePaths()에서 지정하지 않은 필드는 기본적으로 exact 매칭 대상이 됨
  • matcher을 아예 빼버리면 Example의 prob로 설정한 엔티티에 exact 매칭됨

추가로 제공되는 matcher 메서드

  • statsWith()
  • endsWith()
  • contains()


📌 @Query

✔️ @Query
네이밍 쿼리의 가독성이 나빠지는 경우 사용 (너무 길어지는 경우)
아래 메서드처럼 네이밍이 길어지고 복잡해지면 가독성이 매우 나빠진다.

public List<Item> findByItemNameEqualsAndCreatedAtGreaterThanEqualAndUpdatedAtGreaterThanEqaul
            (String name, LocalDateTime createdAt, LocalDateTime updatedAt);

✔️ @Query로 위 쿼리 구성
코드의 양은 많아졌을지라도 쿼리문을 이해할 수만 있다면 가동성 측면에서 더 효과적이다.

@Query(value = 
    "select i from Item i " +
    "where i.name = :name " +
    "and i.createdAt >= :createdAt " +
    "and i.updatedAt >= :updatedAt"
)
public List<Item> findByNameCurrentItem(String name, LocalDateTime createdAt, LocalDateTime updatedAt);

✔️ 매개변수 표현

순서기반 (파라미터의 순서를 기준으로 바인딩) - ❌

where name = ?1 and createdAt >= ?2

이름기반 - 권장 👍

where name = :name and createdAt >= :createdAt
@Param("name") String name
@Param("createdAt") LocalDateTime createdAt

✔️ 특정 필드만 조회 방법 1

인터페이스로 조회 (name과 age를 조회)

public interface NameAndAge {
    String name;
    Integer age;
}
@Query(value= "select u.name, u.age from User u")
List<NameAndAge> findNameAndAge();

✔️ 특정 필드만 조회 방법 2

클래스(DTO)로 조회

  • new 키워드 + 생성자 사용

👍 수강인증

 

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.