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
이다.
# Spring Data Common
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 : 타입 비교