본문 바로가기

TIL

[TIL] 🌱 2023.04.01 - Projection

🛹 목표

목표 난이도 달성 여부
토비의 스프링 🥺 ✔️
패스트 캠퍼스 강의 듣기
😖 ✔️

📋 공부 내용 & 기록

Projection 애노테이션[참고]

 

Spring Data JPA - Projections

Spring Data JPA 게시글은 대부분 인프런의 김영한님의 강의인 '실전! 스프링 데이터 JPA' 기반으로 내용을 정리했습니다. Projections 이 기능은 약간의 도움이 될 때가 있어 앞 부분보다는 잘 듣는 게

devhan.tistory.com

  • Projection은 DB에서 엔티티의 일부 필드만을 가져올 수 있도록 해주는 기술이다.
  • 필요한 필드만 가져올 수 있기 때문에 쿼리 최적화를 할 수 있다.

인터페이스 기반의 Closed Projections

아래의 상황
Projection을 사용하기 전 Spring Data Rest를 사용하여 RESTful API를 지원하지만 Article의 정보에서 사용자 계정의 정보 같이 나오면 좋겠지만 사용자의 정보는 링크로만 존재한다. Article의 정보와 함께 UserAccount 정보도 같이 알기 위해 Projection을 사용하기로 결정
[Spring Data Rest 관련 참고하기]
  • Projection Interfacce를 정의한 후 가져올 필드의 getter 메서드만 작성한다.
  • 인터페이스 애노테이션 중 @Projection의 name은  해당 resource에 접근할 때 사용하는 이름으로 http://localhost:8080/articles/1?projection=withUserAccount 로 해당 자원에 접근할 수 있다.
  • 해당 클래스에 해당하는 Repository에 @RepositoryRestResource(excerptProjection = ArticleCommentProjection.class)를 추가한 후 사용할 수 있다.[excerption 사용법 참고]

<ArticleCommentProjection.java>

@Projection(name = "withUserAccount", types = Article.class)
public interface ArticleProjection {
    Long getId();
    UserAccount getUserAccount();
    String getTitle();
    String getContent();
    LocalDateTime getCreatedAt();
    String getCreatedBy();
    LocalDateTime getModifiedAt();
    String getModifiedBy();
}

<ArticleCommentRepository.java>

@RepositoryRestResource(excerptProjection = ArticleProjection.class)
public interface ArticleRepository extends
        JpaRepository<Article, Long>,
        ArticleRepositoryCustom,
        QuerydslPredicateExecutor<Article>,
        QuerydslBinderCustomizer<QArticle> {

    //underbar를 쓰게되면 Article 객체 안으로 들어가 id로 조회
    Page<Article> findByTitleContaining(String title, Pageable pageable);
    Page<Article> findByContentContaining(String content, Pageable pageable);
    Page<Article> findByUserAccount_UserIdContaining(String userId, Pageable pageable);
    Page<Article> findByUserAccount_NicknameContaining(String nickname, Pageable pageable);

    void deleteByIdAndUserAccount_UserId(Long articleId, String userid);

    @Override
    default void customize(QuerydslBindings bindings, QArticle root) {
        bindings.excludeUnlistedProperties(true);
        bindings.including(root.title, root.content, root.hashtags, root.createdAt, root.createdBy);
        bindings.bind(root.title).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.content).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.hashtags.any().hashtagName).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.createdAt).first(DateTimeExpression::eq);
        bindings.bind(root.createdBy).first(StringExpression::containsIgnoreCase);
    }

장점

  • 필드의 일부만을 가져올 수 있어 쿼리를 최적화할 수 있다.
  • Java 8의 Default 메서드를 사용해서 연산할 수 있다.

Open Projection 방식은 엔티티의 모든 필드를 조회하여 커스텀할 수 있지만, 그렇기 때문에 쿼리를 최적화할 수 없다.

 

 

ObjectMapper의 동작

 

[Spring] ObjectMapper의 동작 방식과 SpringBoot가 제공하는 추가 기능들

이번에는 Spring에서 사용되는 ObjectMapper의 동작 방식에 대한 정리해보도록 하겠습니다. 1. ObjectMapper를 이용한 직렬화(Serialize) [ ObjectMapper의 직렬화(Serialize) 동작 방식 ] ObjectMapper는 리플렉션을 활

mangkyu.tistory.com


참고하면 좋은 사이트

 

Spring Rest Docs 적용 | 우아한형제들 기술블로그

{{item.name}} 안녕하세요? 우아한형제들에서 정산시스템을 개발하고 있는 이호진입니다. 지금부터 정산시스템 API 문서를 wiki 에서 Spring Rest Docs 로 전환한 이야기를 해보려고 합니다. 1. 전환하는

techblog.woowahan.com

 

Spock으로 테스트코드를 짜보자 | 우아한형제들 기술블로그

{{item.name}} Spock으로 테스트코드를 작성한 경험을 공유합니다. 안녕하세요! 우아한형제들 배달의민족/배민라이더스 주문시스템 팀 정용준입니다. 여러분은 어떻게 테스트 코드를 작성하고 계신

techblog.woowahan.com