Spring Boot Querydsl

김정훈·2024년 7월 24일

Spring

목록 보기
21/24

Querydsl

비표준

참고) @Query

@Query 애노테이션 안에 JPQL 문법으로 문자열을 입력하기 때문에 잘못 입력하면 컴파일 시점에 에러를 발견할 수 없습니다. 👉 Querydsl사용

public interface MemberRepository extends JpaRepository<Member, Long> {
    @Query("SELECT m FROM Member m WHERE m.email LIKE :k1 AND m.userName LIKE :k2 ORDER BY m.createdAt DESC ")
    List<Member> getMembers(@Param("k1") String key1, @Param("k2") String key2);
}
	@Test
    void test4(){
        List<Member> members = memberRepository.getMembers("%ser%","%용%");
        members.forEach(System.out::println);
    }

의존성 및 설정

implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.1.0:jakarta'

settings.gradle

tasks.named('test') {
	useJUnitPlatform()
}

def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile

sourceSets {
	main.java.srcDirs += [ querydslDir ]
}

tasks.withType(JavaCompile) {
	options.getGeneratedSourceOutputDirectory().set(file(querydslDir))
}

clean.doLast {
	file(querydslDir).deleteDir()
}

QueryDslPredicateExecutor

QueryDslPredicateExecutor를 함께 상속 👉 기존 Repository 메서드에 Predicate가 매개변수인 메서드가 추가된다.

Predicate : 판별식

반환값
BooleanExpression : 최종 조건 결과
StringExpression : 조건 더 추가 가능

MemberRepository

public interface MemberRepository extends JpaRepository<Member, Long>, QuerydslPredicateExecutor<Member> {
}

 	@Test
    void test1() {
        QMember member = QMember.member;
        BooleanExpression c1 = member.userName.contains("용");

        List<Member> members = (List<Member>) memberRepository.findAll(c1);

        members.forEach(System.out::println);
    }

Q클래스

eq : =
lt : <
loe : <=
gt : >
goe : >=

BooleanBuilder

Predicate의 구현 클래스
조건식이 여러개인 경우 사용
여러 검색조건을 만드는 경우 사용
게시글 검색(검색조건 다양함)
논리조건 처리할 때 사용
사용빈도 높음

and(Predicate...)
or(Predicate...)
not(Preadicate...)

관계매핑

지연로딩
JPAQueryFactory
JPAQuery

메서드

1. BooleanBuilder

	@Test
    void test7(){
        QBoardData boardData = QBoardData.boardData;

        BooleanBuilder andBuilder = new BooleanBuilder();
        andBuilder.and(boardData.subject.contains("제목"))
                .and(boardData.member.userName.eq("user01@test.org"));

        BooleanBuilder orBuilder = new BooleanBuilder();
        orBuilder.or(boardData.seq.eq(2L))
                .or(boardData.seq.eq(3L))
                .or(boardData.seq.eq(4L));

        andBuilder.and(orBuilder); //andBuilder orBuilder 같이 사용하고싶을 때 매개변수로해서 통합

        JPAQuery<BoardData> query = queryFactory.selectFrom(boardData)
                .leftJoin(boardData.member)
                .fetchJoin()
                .where(andBuilder); // 반환값 BooleanExpression - Predicate(상위클래스)
        List<BoardData> items = query.fetch();
        items.forEach(System.out::println);
    }

2. offset(), limit()

@Test
    void test7(){
        QBoardData boardData = QBoardData.boardData;

        BooleanBuilder andBuilder = new BooleanBuilder();
        andBuilder.and(boardData.subject.contains("제목"))
                .and(boardData.member.userName.eq("user01@test.org"));
        /*
        BooleanBuilder orBuilder = new BooleanBuilder();
        orBuilder.or(boardData.seq.eq(2L))
                .or(boardData.seq.eq(3L))
                .or(boardData.seq.eq(4L));

        andBuilder.and(orBuilder); //andBuilder orBuilder 같이 사용하고싶을 때 매개변수로해서 통합

         */
        JPAQuery<BoardData> query = queryFactory.selectFrom(boardData)
                .leftJoin(boardData.member)
                .fetchJoin()
                .where(andBuilder) // 반환값 BooleanExpression - Predicate(상위클래스)
                .offset(3) //조회 시작 레코드 위치 3번 행부터 조회 시작
                .limit(3); // 3개 레코드로 한정 갯수 제한
        List<BoardData> items = query.fetch();
        items.forEach(System.out::println);
    }

3. OrderBy

PathBuilder

	@Test
    void test7(){
        QBoardData boardData = QBoardData.boardData;

        BooleanBuilder andBuilder = new BooleanBuilder();
        andBuilder.and(boardData.subject.contains("제목"))
                .and(boardData.member.userName.eq("user01@test.org"));


        PathBuilder<BoardData> pathBuilder = new PathBuilder<>(BoardData.class, "boardData");

        JPAQuery<BoardData> query = queryFactory.selectFrom(boardData)
                .leftJoin(boardData.member)
                .fetchJoin()
                .where(andBuilder) // 반환값 BooleanExpression - Predicate(상위클래스)
                .offset(3) //조회 시작 레코드 위치 3번 행부터 조회 시작
                .limit(3) // 3개 레코드로 한정 갯수 제한
                .orderBy(new OrderSpecifier(Order.DESC, pathBuilder.get("createdAt")),
                        new OrderSpecifier(Order.ASC, pathBuilder.get("subject"))
                );

        List<BoardData> items = query.fetch();
        items.forEach(System.out::println);
    }

profile
안녕하세요!

0개의 댓글