반응형
해당 강의는 코드 위주로 진행됩니다. 실질적인 객체 처리를 담당하는 코드는 링크에서 확인하시길 바랍니다.
* DB 연동 코드 구현 방법
- Repository 인터페이스를 상속한다.
- 정해진 규칙에 따라 메서드를 추가한다.
* 식별자로 엔티티 조회
- findById
- T findById(Id id)
- 없으면 null을 반환한다.
- Optional<T> findById(ID id)
- 없으면 empty Optional을 반환한다.
- T findById(Id id)
public interface UserRepository extends Repository<User, String> {
Optional<User> findById(String email);
}
* 엔티티 삭제
- delete
- void delete(T entity)
- void deleteById(Id id)
- 내부적으로 findById()로 엔티티를 조회한 뒤 delete()로 삭제
- 삭제할 대상이 존재하지 않으면 예외 발생
public interface UserRepository extends Repository<User, String> {
Optional<User> findById(String email);
void delete(User user);
}
Optional<User> userOpt = userRepository.findById("email@email.com");
userOpt.ifPresent(user -> {
userRepository.delete(user);
});
* 엔티티 저장 메서드
- save
- void save(T entity)
- T save(T entity)
public interface UserRepository extends Repository<User, String> {
User save(User user);
or
void save(User user);
}
User savedUser = userRepository.save(new User(...));
User user = new User(...);
userRepository.save(user);
* save() 호출 시 실행 쿼리
- save()를 호출할 때 실행되는 쿼리를 보면, 넘겨준 User 엔티티를 기반으로 select가 먼저 실행된다.
- 그럼 select는 왜 실행될까? 이는 Repository의 구현 때문에 그런다.
* save() 동작 방식
- 위 코드는 Spring Data JPA가 제공하는 save()메서드의 기본적인 구현이다.
- 조건절에서, 해당 엔티티가 새 엔티티인지를 찾는다.
- 새 엔티티면 persist를 한다.
- 그렇지 않으면 merge 한다. 이 merge 때문에 select를 먼저 하게 된다.
- 새 엔티티인지를 판단하는 기준은 다음과 같다.
- Persistable을 구현한 엔티티는 isNew()로 판단한다.
- @Version 속성이 있는 경우 버전 값이 null이면 새 엔티티로 판단한다.
- 식별자가 참조 타입이면 식별자가 null 이면 새 엔티티로 판단한다.
- 식별자가 숫자 타입이면 0이면 새 엔티티로 판단한다.
* Persistable 구현 예
- 간혹 불필요한 select 쿼리를 실행하고 싶지 않거나, 원치 않는 merge가 되는 경우도 있을 수 있다.
- 이를 방지하기 위해서는 Persistable을 구현하고 select 쿼리가 실행되지 않게 방지해야한다.
- isNew()를 의 값에 따라서, 새로운 엔티티인지, 아닌지를 구분할 수 있다.
- 위의 예시 코드에서는 markNotNew()에 @PrePersist 애너테이션을 붙여, 엔티티가 저장될 때, boolean isNew를 false로 바꿔 중복 저장을 방지하고 있다.
- 새로운 엔티티를 저장할때는 isNew()에서 항상 true를 반환하기 때문에 select쿼리와 merge과정을 생략하고 즉시 persist를 진행할 수 있다.
* 특정 조건으로 찾기
- findBy프로퍼티(값) : 프로퍼티가 특정 값인 대상
- List<User> findByName(String name); : 유저 엔티티 중 name 속성 값이 파라미터 name과 같은 엔티티들의 리스트를 찾는다.
- List<Hotel> findByGradeAndName(Grade G, String name) : AND 연산도 처리할 수 있다.
- 조건 비교
- List<User> findByNameLike(String keyword)
- List<User> findByCreatedAtAfter(LocalDateTime time)
- List<Hotel> findByYearBetween(int from, int to)
- LessThan, isNull, Containing, In 등 다양한 조건 비교를 사용할 수 있다.
- findAll() : 모두 조회한다.
* 정리
- 정해진 규칙에 따라 인터페이스만 작성하면 된다.
- 주의
- findBy 메서드를 남용하면 안된다.
- 검색 조건이 단순하지 않으면 findBy 대신 @Query, SQL, 스펙 / QueryDSL을 사용한다.
반응형
'Programming > JPA & Spring Data JPA 기초' 카테고리의 다른 글
24. Specification을 이용한 검색 조건 지정 (0) | 2023.04.18 |
---|---|
23. 정렬, 페이징, @Query (0) | 2023.04.10 |
21. Spring Data JPA 시작하기 (0) | 2023.04.06 |
20. 기타 AttributeConverter, @Formula, @DynamicUpdate(@DynamicInsert), @Immutable, @Subselect (0) | 2023.04.05 |
19. Criteria 소개 (0) | 2023.04.04 |
댓글