스프링 데이터 JPA
- @JpaRepository (interface)
H2 Database 처음 기본설정
- h2.jar 실행
- JDBC URL : jdbc:h2:~/datajpa
- → datajpa.mv.db 파일이 생성됨
- 로그아웃
- JDBC URL : jdbc:h2:tcp://localhost/~/datajpa
쿼리의 파라미터 로그 남기기
- 라이브러리 추가
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7'
주의
- T findOne(ID) → Optional<T> findById(ID) 로 변경
- 제네릭 타입
- T : 엔티티
- ID : 엔티티의 식별자 타입
- S : 엔티티와 그 자식 타입
- 주요 메서드
- save(S)
- delete(T)
- findById(ID)
- getOne(ID) : 엔티티를 프록시로 조회
- findAll(...) : Sort나 Pageable 가능
쿼리메서드
- 메서드 이름으로 쿼리 생성
- findByUsername
- findByUsernameAndAgeGreaterThan
- Username(String) / Age(int) → 파라미터 2개
- Greater Than : 크면
- 방법
- 조회: find...By, read...By, query...By...
- findHelloBy
- Count(long) : count...By
- EXISTS(boolean) : exists...By
- 삭제 : delete...By, remove...By
- DISTINCT : findDistinct
- findMemberDistinctBy
- LIMIT : findFirst3, findFirst, findTop, findTop3
- 조회: find...By, read...By, query...By...
메서드에 쿼리 사용 ( @Query )
- @Param 활용
- 로딩 시점에 오류 발견!
@Query("select m from Member m where m.username = :username and m.age = :age") List<Member> findUser(@Param("username") String username, @Param("age") int age);
@Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t") List<MemberDto> findMemberDto();
- in
@Query("select m from Member m where m.username in :name") List<Member> findByNames(@ Param("names") List<String> names);
반환 타입
- 스프링 데이터 JPA는 유연한 반환 타입 지원
- 컬렉션
- List<Member> : 없으면 empty
- 단건
- Member : 없으면 null
- Optional<Member> : 없으면 empty
- 컬렉션
페이징 / 정렬
- 순수 JPA 페이징
public List<Member> findByPage(int age, int offset, int limit){ return em.createQuery("select m from Member m where m.age = :age order by m.username desc") .setParameter("age", age) .setFirstResult(offset) .setMaxResults(limit) .getResultList(); } public long totalCount(int age){ return em.createQuery("select count(m) from Member m where m.age = :age", Long.class) .setParameter("age", age) .getSingleResult(); }
- 스프링 데이터 JPA 페이징, 정렬
- Page : count 쿼리 O
- Slice : count 쿼리 X, 다음페이지 확인가능
- List : count쿼리X, 결과만 반환
페이지 유지 → DTO 변환
Page<Member> page = memberRepository.findByAge(age, pageRequest); Page<MemberDto> dtoPage = page.map(m -> new MemberDto(m.getId(), m.getUsername(), null));
벌크성 수정 쿼리
: 모든 직원의 연봉을 10%인상 등.. 한번에 처리
@Modifying(clearAutomatically = true) // 변경. 없으면 오류 @Query("update Member m set m.age=m.age+1 where m.age >= :age") int bulkAgePlus(@Param("age") int age);
- 연산 전 수행 = @Modifying(clearAutomatically = true)
- em.flush()
- em.clear()
@EntityGraph
: 연관관계들을 join fetch해서 가져올지 정해줌
@Override @EntityGraph(attributePaths = {"team"}) List<Member> findAll(); @EntityGraph(attributePaths = {"team"}) @Query("select m from Member m") List<Member> findMemberEntityGraph();
hint
: DB조회만 사용할 때 (최적화)
@QueryHints(value = @QueryHint(name = "org.hibernate.readOnly", value = "true")) Member findReadOnlyByUsername(String username);
Auditing
- 엔티티를 생성, 변경할 때, 변경한 사람, 시간 추적
- 등록일
- 수정일
- 등록자
- 수정자
- 순수 JPA
@MappedSuperclass public class JpaBaseEntity { @Column(updatable = false) private LocalDateTime createDate; private LocalDateTime updateDate; @PrePersist // 최초등록 public void prePersist(){ LocalDateTime now = LocalDateTime.now(); createDate = now; updateDate = now; } @PreUpdate public void preUpdate(){ // 업데이트 updateDate = LocalDateTime.now(); } }
- 스프링 데이터 JPA
@EnableJpaAuditing // 메인에 추가 // @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public class BaseEntity { @CreatedDate // 생성 @Column(updatable = false) private LocalDateTime createDate; @LastModifiedDate // 업데이트 private LocalDateTime lastModifiedDate; }
'공부 > Spring' 카테고리의 다른 글
[Spring] 스프링의 탄생과 개념 (0) | 2022.04.19 |
---|---|
Querydsl (0) | 2021.10.04 |
JPA + JPQL (0) | 2021.09.24 |
스프링 공부 0 (0) | 2021.09.05 |
스프링 공부 1 (0) | 2021.09.05 |
댓글