비표준
@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를 함께 상속 👉 기존 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);
}
eq : =
lt : <
loe : <=
gt : >
goe : >=
Predicate의 구현 클래스
조건식이 여러개인 경우 사용
여러 검색조건을 만드는 경우 사용
게시글 검색(검색조건 다양함)
논리조건 처리할 때 사용
사용빈도 높음
and(Predicate...)
or(Predicate...)
not(Preadicate...)
지연로딩
JPAQueryFactory
JPAQuery
@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);
}

@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);
}

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);
}
