0516 ~ 0529


# 0516 ~ 0529

# 0519 - Querydsl 튜플이나 DTO로 결과 반환하기

  • 프로젝션 : select 대상을 지정하는 일

# 튜플

  • com.querydsl.core.Tuple 사용
List<Tuple> result = queryFactory
                        .select(member.username, member.age)
                        .from(member)
                        .fetch();

for (Tuple tuple : result) {
    String username = tuple.get(member.username);
    Integer age = tuple.get(member.age);
    
    System.out.println("username=" + username);
    System.out.println("age=" + age);
}

# DTO 사용하기

  • 프로퍼티 접근
  • 필드 직접 접근
  • 생성자 사용
  • @QueryProjection

# Bean() : getter, setter, default constructor 필요

List<MemberDto> result = queryFactory
                          .select(Projections.bean(MemberDto.class,
                                        member.username,
                                        member.age))
                          .from(member)
                          .fetch();

# 필드 직접 접근 : getter, setter 필요 없음, 바로주입

List<MemberDto> result = queryFactory
                        .select(Projections.fields(MemberDto.class,
                                    member.username,
                                    member.age))
                        .from(member)
                        .fetch();

# 생성자 사용

List<MemberDto> result = queryFactory
                            .select(Projections.constructor(MemberDto.class,
                                      member.username,
                                      member.age))
                            .from(member)
                            .fetch();

DTO의 필드명이 다를경우 ExpressionUtils.as(source,alias) -> 필드나, 서브 쿼리에 별칭 적용

List<UserDto> fetch = queryFactory
                        .select(Projections.fields(UserDto.class,
                                member.username.as("name"),
                                ExpressionUtils.as(
                                    JPAExpressions
                                    .select(memberSub.age.max())
                                    .from(memberSub), "age")
                                ))
                        .from(member)
                        .fetch();

# @QueryProjection

  • DTO 생성자에 @QueryProjection을 사용하면 DTO도 Q파일로 생성된다.
import com.querydsl.core.annotations.QueryProjection;

public class MemberDto {

    private String username;

    private int age;

    public MemberDto() {
    }

    @QueryProjection
    public MemberDto(String username, int age) {
        this.username = username;
        this.age = age;
    }
}
  • 생성된 Q파일 사용
queryFactory
    .select(new QMemberDto(member.username, member.age))
    .from(member)
    .fetch();

특징

  • 컴파일오류로 사전 버그 확인.
  • 컴파일 시점에 타입 체크, 파라미터 개수체크 등 가능.
  • 단, DTO가 Querydsl에 의존성이 생긴다.

# 0520 - [Spring Data Common] Repository, @NoRepositoryBean

# Spring Data

Spring Data는 Spring에서 SQL & NoSQL 저장소 지원 프로젝트의 묶음이다.
Spring에서 제공하는 여러 저장소 지원 프로젝트의 공통 프로젝트가 바로 Spring Data Common이다. image

# Spring Data Common

image JpaRepository 인터페이스는 Spring Data Jpa에서 제공하는 인터페이스이다.

JpaRepository가 상속받는 PagingAndSortingRepository는 Spring Data Common에서 제공하는 인터페이스이다.(PagingAndSortingRepository는부터는 Spring Data Common단의 인터페이스)

  • PagingAndSortingRepository : 페이징, 정렬 지원하는 메서드 제공
  • CrudRepository : CRUD를 지원하는 메서드 제공
  • Repository : Marker 인터페이스. 마커용 외에 다른 기능은 없다

# @NoRepositoryBean

JpaRepository, PagingAndSortingRepository, CurdRepository의 중간단계 Repository를 보면 @NoRepositoryBean 어노테이션이 선언되어있다.

package org.springframework.data.jpa.repository;

/**
 * JPA specific extension of {@link org.springframework.data.repository.Repository}.
 *
 * @author Oliver Gierke
 * @author Christoph Strobl
 * @author Mark Paluch
 */
@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
    ...
}

중간 Repository에 @NoRepositoryBean 어노테이션이 붙어있는 이유는 다음과 같다.

  • Repository 인터페이스를 상속받았기 때문에 Spring Data Jpa 또는 다른 저장소용 Repository가 실제 빈을 만들지 않도록 사용.
  • 실제 사용되는 Repository가 아님을 표시함.

# 0522 - isEqualTo vs isSameTo(isInstanceOf)

  • isSameAs : 주소 비교. 메모리 상에서 같은 객체를 참조하는지 확인
  • isEqualTo : 값 비교. 객체가 서로 같은 값을 가지고 있는지 확인(객체를 비교하게 되는 경우 isSameAs와 같이 참조를 비교)
  • isInstanceOf : 타입 비교
Last update: September 13, 2022 21:44
Contributors: ahnjs