순수 JPA 리포지토리와 Querydsl


순수 JPA 리포지토리

@Repository
public class MemberJpaRepository {
	private final EntityManager em;
	private final JPAQueryFactory queryFactory;

	public MemberJpaRepository(EntityManager em) {
		this.em = em;
		this.queryFactory = new JPAQueryFactory(em);
	}

	public void save(Member member) {
		em.persist(member);
	}

	public Optional<Member> findById(Long id) {
		Member findMember = em.find(Member.class, id);
		return Optional.ofNullable(findMember);
	}

	public List<Member> findAll() {
		return em.createQuery("select m from Member m", Member.class).getResultList();
	}

	public List<Member> findByUsername(String username) {
		return em.createQuery("select m from Member m where m.username = :username", Member.class)
							.setParameter("username", username)
							.getResultList();
	}

}

Querydsl

public List<Member> findAll_Querydsl() {
	return queryFactory
					.selectFrom(member).fetch();
}

public List<Member> findByUsername_Querydsl(String username) {
	return queryFactory
					.selectFrom(member)
					.where(member.username.eq(username))
					.fetch();
}

다음과 같이 JPAQueryFactory 를 스프링 빈으로 등록해서 주입받아 사용해도 된다.

@Bean
JPAQueryFactory jpaQueryFactory(EntityManager em) {
	return new JPAQueryFactory(em);
}

참고 : 동시성 문제는 걱정하지 않아도 된다. 스프링이 주입해주는 엔티티 매니저는 실제 동작 시점에 진짜 엔티티 매니저를 찾아주는 프로시용 가까 엔티티 매니저이다. 이 가짜 엔티티 매니저는 실제 사용 지점에 트랜잭션 단위로 실제 엔티티 매니저(영속성 컨텍스트)를 할당해준다.

동적 쿼리와 성능 최적화 조회 - Builder 사용


MemberTeamDto - 조회 최적화용 DTO 추가

@Data
public class MemberTeamDto {
	private Long memberId;
	private String username;
	private int age;
	private Long teamId;
	private String teamName;

	@QueryProjection
	public MemberTeamDto(Long memberId, String username, int age, Long teamId, String teamName) {
		this.memberId = memberId;
		this.username = username;
		this.age = age;
		this.teamId = teamId;
		this.teamName = teamName;
	}

}

@QueryProjection 을 추가했다. QMemberTeamDto 를 생성하기 위해 ./gradlew compileQuerydsl을 한번 실행하자.

회원 검색 조건

@Data
public class MemberSearchCondition {

	//회원명, 팀명, 나이(ageGoe, ageLoe)
	private String username;
	private String teamName;
	private Integer ageGoe;
	private Integer ageLoe;

}