Spring 3.x build.gradle → Entity 설계

ext {
	set('querydslVersion', "5.0.0")  // QueryDSL 버전 명시적으로 설정
}
dependencies {
	implementation "com.querydsl:querydsl-jpa:${querydslVersion}:jakarta"
	annotationProcessor "com.querydsl:querydsl-apt:${querydslVersion}:jakarta"
	annotationProcessor "jakarta.annotation:jakarta.annotation-api"
	annotationProcessor "jakarta.persistence:jakarta.persistence-api"
}

def querydslSrcDir = 'src/main/generated'
clean {
	delete file(querydslSrcDir)
}

Gradle IntelliJ 사용법

Test code

@SpringBootTest
@Transactional
class QuerydslApplicationTests {
	@Autowired
	EntityManager em;
	
	@Test
	void contextLoads() {
		Hello hello = new Hello();
		em.persist(hello);
		
		JPAQueryFactory query = new JPAQueryFactory(em);
		
		QHello qHello = QHello.hello; //Querydsl Q타입 동작 확인
		Hello result = query
			.selectFrom(qHello)
			.fetchOne();
			
		Assertions.assertThat(result).isEqualTo(hello);
		//lombok 동작 확인 (hello.getId())
		Assertions.assertThat(result.getId()).isEqualTo(hello.getId());
		}
}

기본 문법

EntityManager 로 JPAQueryFactory 생성

JPQL: 문자(실행 시점 오류), Querydsl: 코드(컴파일 시점 오류)

JPQL: 파라미터 바인딩 직접, Querydsl: 파라미터 바인딩 자동 처리

JPAQueryFactory를 필드로 제공하면 동시성 문제는 어떻게 될까? 동시성 문제는 JPAQueryFactory를 생성 할 때 제공하는 EntityManager(em)에 달려있다.

스프링 프레임워크는 여러 쓰레드에서 동시에 같은 EntityManager에 접근해도, 트랜잭션 마다 별도의 영속성 컨텍스트를 제공하기 때문에, 동시성 문제는 걱정하지 않아도 된다.

    **@PersistenceContext
    EntityManager em;**

    **JPAQueryFactory queryFactory;**

    @BeforeEach
    public void before() {

        queryFactory = new JPAQueryFactory(em);
        Team teamA = new Team("teamA");
        Team teamB = new Team("teamB");
        em.persist(teamA);
        em.persist(teamB);
        Member member1 = new Member("member1", 10, teamA);
        Member member2 = new Member("member2", 20, teamA);
        Member member3 = new Member("member3", 30, teamB);
        Member member4 = new Member("member4", 40, teamB);
        em.persist(member1);
        em.persist(member2);
        em.persist(member3);
        em.persist(member4);
    }
    
    import static study.querydsl.entity.QMember.*;
    
    @Test
    public void startQuerydsl(){
        **QMember m = member;**

        **Member** findMember = queryFactory
            .select(m)
            .from(m)
            .where(m.username.eq("member1"))
            .fetchOne();

        assertThat(findMember.getUsername()).isEqualTo("member1");
    }

기본 Q-Type 활용

QMember qMember = new QMember("m"); //별칭 직접 지정
QMember qMember = QMember.member; //기본 인스턴스 사용

다음 설정을 추가하면 실행되는 JPQL을 볼 수 있다