스프링데이터 + JPA/스프링 데이터 JPA 30

29. 네이티브 쿼리

먼저 사실 Jpa를 사용하면 네이티브 쿼리는 왠만하면 사용하지 않는 게 좋음. 정말 정말 방법이 없을 때 최종적으로 사용하는 게 네이티브 쿼리. (리포지토리가 DB끼리의 표준화가 안될 터이니..) 일단 그래도 정말 가끔 어쩔 수 없어서 짜야 할 수도 있으니, 알 긴 해야할 듯. 방법은 정말 간단함. 그냥 Spring Data Jpa에서 @Query(value = "select * from member where username = ?", nativeQuery = true) Member findByNativeQuery(String username); jpql 직접 할 때 처럼 저렇게 @Query하고 쿼리 적는 건 똑같은데, 아마 jpql과 문법이 달라 문자열이지만 오류를 표시해 줌. 그 때 nativeQu..

28. Projections

이번거는 앞의 2개와 달리 때때로 도움이 될 수 있음. 일단 Jpa자체가 엔티티를 대상으로 조회하려고 만들어 진 거임. 근데 뭐 예를들어 엔티티 자체가 아니라 엔티티의 값 하나만, Member의 username 하나만 조회하고 싶으면? 쉽게 이야기 해서, Projections 직역은 예상, 계획인데 select () from 저기 select 절 뒤에 들어갈 거라고 보면 된다. 사용법도 간단함 public interface UsernameOnly { String getUsername(); } 먼저 이렇게 인터페이스를 만듦. 저 메소드명이 중요한데, 가져올 것의 프로퍼티명으로 만들어 버리셈. 당연히 타입은 맞춰주고. 그 다음, List findProjectionsByUsername(String userna..

27. Query By Example

이거는 보기에 생각보다 좋아보인다. @Test public void queryByExample(){ Team teamA = new Team("teamA"); em.persist(teamA); Member m1 = new Member("m1", 0, teamA); Member m2 = new Member("m2", 0, teamA); em.persist(m1); em.persist(m2); em.flush(); em.clear(); Member member = new Member("m1"); Example example = Example.of(member); List result = memberRepository.findAll(example); assertThat(result.size()).isEqualT..

26. 명세 (Specifications)

이제 SpringDataJpa의 전반적인 부분은 어느정도 배웠고, 이제 나머지 기능들에 대해서 소개를 좀 할건데, 이것들은 대부분 복잡도에 비해 다른 좋은 대안들이 있어서 사실 잘 안쓴다. 명세, Query By Example, Projections, 네이티브 쿼리 이렇게 4가지에 대해 배울건데, 4번째 네이티브 쿼리 빼고는 위에 3가지는 소개 하고, 왜 안쓰는지 알아볼 예정. 명세라는 것은 뭐냐, 우리가 where문에서 and, or 해서 조건같은 걸 막 넣는데, 그걸 조립해서 쓸 수 있도록 만든 개념 (근데 이건 이미 QueryDSL에서..) 그냥 나도 한번 써보는 정도는 보여 줄 거임. public interface MemberRepository extends JpaRepository, 커스텀할거야..

25. 새로운 엔티티 구별방법, isNew

@Transactional @Override public S save(S entity) { Assert.notNull(entity, "Entity must not be null"); if (entityInformation.isNew(entity)) { entityManager.persist(entity); return entity; } else { return entityManager.merge(entity); } } 이 부분에서 isNew(T) 부분에 대해서 말할거임. 기본 전략은 식별자로 식별자가 객체면 null인지로 파악 식별자가 자바 기본타입이면 0인지로 파악 Persistable 인터페이스를 구현하여 판단 로직 변경이 가능함. @Entity @Getter public class Item { @I..

24. 스프링 데이터 JPA 구현체 분석

스프링 데이터 JPA는 인터페이스를 만들어 놓으면 자동으로 구현체를 만들어 준다. 그 구현체를 분석해 볼 것이다. 애초에 예시로 구현체 모습을 제공해 주었다. SimpleJpaRepository 라는 것이다. package org.springframework.data.jpa.repository.support; 이 위치에 있다. 좀 많긴 하다. 그래도 일단 코드 한번 남겨 본다. @Repository @Transactional(readOnly = true) public class SimpleJpaRepository implements JpaRepositoryImplementation { private static final String ID_MUST_NOT_BE_NULL = "The given id mus..

23. 웹 확장 페이징과 정렬

스프링 데이터 JPA는 페이징과 정렬을 웹에서 편리하게 사용할 수 있도록 기능을 제공함. @GetMapping("/members") public Page list(Pageable pageable){ return memberRepository.findAll(pageable); } 이렇게 인자로 Pageable로 받으면, 아마 argumentResolver에 어댑팅 되면서 그 때 스프링이 PageRequest였나 그걸 생성해서 값을 채운다음 저렇게 인자로 넣어 줄 거임. 그럼 그거 받아서 저 Pageable 인자로 받는 findAll은 PagingAndSortingRepository(JpaRepository가 상속받은 인터페이스 중 하나)에 있는거임 일단 그래서 요청해보면, http://localhost:8..

22. Web확장 도메인 클래스 컨버터

스프링 데이터 JPA에서 제공해주는 웹 확장 기능 2가지가 있음. 그 중 도메인 클래스 컨버터 이게 뭐냐면, 말 그대로 컨버터다. 웹으로 받아온 걸 도메인 클래스로 변환해주는. @GetMapping("/members2/{id}") public String findMember2(@PathVariable("id") Member member){ return member.getUsername(); } 이런거다. 왜냐하면 저렇게 받는게 id니까 이런 식으로 할 수 있는거다. 스프링이 중간에 컨버팅 해주고 넣어준다. select m1_0.member_id, m1_0.age, m1_0.create_by, m1_0.created_date, m1_0.last_modified_by, m1_0.last_modified_da..

21. Auditing

Auditing 직역은 감사하다. 감사를 수행하다. 이게 무슨 기능이냐면, 보통 테이블을 만들 때 등록일, 수정일 이 두개는 기본으로 깐다. 감사하다. 라는 뉘앙스 대로 뭔가 감찰하고, 뭐 그런건데, 저런 등록일이나 수정일, 더 나아가서는 등록자나 수정자까지 자동으로 넣어주는 기능이다. 등록자 수정자는 어떤 관리자가 수정을 했고 취소를 했는지 등 시스템 관리자 id? 등으로 넣어줌. 실무에서 많이 사용함. 그럼 우선 jpa로 등록일, 수정일 적용 먼저 보통 이런 것들은 모든 테이블에 공통적으로 들어가는 사항이라, @Getter @MappedSuperclass public class JpaBaseEntity { @Column(updatable = false) private LocalDateTime crea..

20. 확장기능. 사용자 정의 리포지토리

이거는 정말 많이 쓸 것이다. 이게 뭐냐면, 우리가 기존의 SpringDataJPA에서는 메소드명으로 쿼리 지정, 뭐 JPQL직접 작성 등 여튼간에 SpringDataJPA에서가 제공해주는 방식으로만 정의할 수 있었다. 인터페이스이기 때문에. SpringDataJPA이란 JPA를 이용한 것들의 자동구현을 도와주는 라이브러리 이기 때문에. 근데 만약 우리가 jpql이 아니라 순수 sql을 이용해, jdbc template를 이용해 DB에 쿼리를 전달하고 싶다면? 아니면 QueryDSL을 쓰고 싶다면? 어딘가에 직접 우리가 그걸 구현해 줘야 한다. 아쉽게도, SpringDataJPA가 직접 QueryDSL과 뭐 연동해서 해 주는 것은 없다. 우리가 직접 구현을 해 줘야 한다. 그러면 어떻게 하느냐, 먼저, ..