public interface MemberReposiotry extends JpaRepository<Member,Long> {
//Spring Data JPA는 다양한 반환값 타입을 제공한다.
//1] 반환 타입 : 컬렉션
List<Member> findListByUsernameS(String username);
// 2] 반환 타입 : 단건
Member findMemberByUsername(String username);
//3] 반환 타입 : 단건 with Optional
Optional<Member> findOptionalByUsername(String username);
@Test@Transactional
public void returnTypes() {
Member member1 = new Member("member1", 10);
Member member2 = new Member("member2", 20);
repository.save(member1);
repository.save(member2);
// Spring Data JPA은 컬렉션을 반환 타입으로 지원!
List<Member> findMembers = repository.findListByUsernameS("member1");
//만약, "member1"이 DB에 없다면, List로 NULL이 반환이 될까??
//->NOPE!!! [빈 컬렉션], List 같은 경우, new ArrayList<>()를 반환한다.
// 고로 if( findMembers == null ), else... 뭐 이런 코드는 안 짜도 된다.
// (JPA는 해당 쿼리에 대한 결과가 없어도, List에 NULL값을 반환하지 않는다는 스펙이 있다)
// 만약 username이 UNIQUE하다면 굳이 컬렉션(List)로 받을 필요가 없다.
Member findMember = repository.findMemberByUsername("member1");
// 만약 username에 해당하는 Member가 없을 수도 있는 경우에는 NULL을 반환을 한다.
//-> 순수 JPA는 NoResultException을 터트려서 버리지만,
//Spring Data JPA는 Exception을 터트리지 않고, try-catch를 내부적으로 돌려서 null을 반환한다.
//실제로 Excpetion을 터트리는 것이 낫냐, 아니면 null을 반환하는 것이 낫냐라는 논쟁이 있었다.
// 그러나 JAVA 8에서부터 Optional이 나오면서 이 논쟁은 사라졌다.
// -> 1개의 객체에 대한 조회 결과가 있을 수도, 없을 수도 있는 경우에는 [Optinal]을 사용하자!
Optional<Member> member3 = repository.findOptionalByUsername("member3");
//근데, 위 코드에서 만약 조회의 결과가 단건이 아니라 2개 이상이면??
//->그때는 Optional이라도 예외가 터진다.
// Spring Data JPA는 이때에 InCorrectResultSizeDataAccessException이라는 [Spring]에서 정의된 Excpetion으로 바꿔서 예외를 터트림.
// 우리는 현재 Repository는 JPA로 구현을 하였지만, Mongo로 Repository를 구현할 수도 있고, 다른 방식으로 Repository를 구현할 수가 있다.
// 그러나 Spring은 그 어떠한 방법으로 구현을 하였다고 하여도, 조회 결과가 2개이상인 것에 대해서는 모두 [InCorrectResultSizeDataAccessException]
// 으로 반환을 한다.
// -> 장점 : Service 계층에서 JPA_Repository를 사용하다가, MONGO_Repository로 변경을 하였을 때, [똑같은] 예외가 올라오므로
// 예외 처리에 대한 [클라이언트 코드의 수정을 하지 않아도 된다](OCP 원칙)
}
스프링 데이터 JPA 메뉴얼을 보면 정말 다양한 반환 타입을 지원하는 것을 확인할 수가 있다.
'CS 잡지식' 카테고리의 다른 글
Spring Data JPA가 제공하는 막강한 [페이징],[정렬] (1) | 2023.05.12 |
---|---|
Paging에서의 offset과 limit의 정확한 의미!! (0) | 2023.05.11 |
@NamedQuery vs @Query( JPA vs Spring Data JPA ) (0) | 2023.05.11 |
쿼리 메서드(Feat.Spring Data JPA) (0) | 2023.05.10 |
JPA가 제공하는 remove() 메서드에 대한 주의!! (0) | 2023.05.10 |