📦 Database/QueryDSL

Query Builder - 검색 조건 쿼리

신건우 2023. 5. 20. 18:54

💡검색 조건 쿼리

검색 조건은 .and() & .or() 메서드 체인으로 연결하여 조건을 추가할 수 있다.

@SpringBootTest  
@Transactional  
class SearchTest @Autowired constructor(  
    @PersistenceContext  
    val em: EntityManager,  
    val queryFactory: JPAQueryFactory  
) {  

    /** @desc 기본 검색 쿼리 */    
    @Test  
    fun search() {  
        val m: QMember = QMember("m")  

        val findMember = queryFactory  
            .selectFrom(m)  
            .where(m.name.eq("member1").and(m.age.eq(10)))  
            .fetchOne()  

        assertThat(findMember?.name).isEqualTo("member1")  

        m.name.eq("member1")  
        m.name.ne("member2")  
        m.name.eq("member1").not()  

        m.name.isNotNull  

        m.age.`in`(10, 20)  
        m.age.notIn(10, 20)  
        m.age.between(10, 30)  

        m.age.goe(30) // age >= 30  
        m.age.gt(30) // age > 30  
        m.age.loe(30) // age <= 30  
        m.age.lt(30) // age < 30  

        m.name.like("member%") // like 검색  
        m.name.contains("member") // like %member% 검색  
        m.name.startsWith("member") // like member% 검색  
    }  

    /** @desc And 조건을 파라미터로 처리 */    
    @Test  
    fun searchAndParam() {  
        val m: QMember = QMember("m")  

        val result: List<Member> = queryFactory  
            .selectFrom(m)  
            .where(m.name.eq("member1"))  
            .fetch()  

        assertThat(result.size).isEqualTo(1)  

        //List  
        val fetch: List<Member> = queryFactory  
            .selectFrom(m)  
            .fetch()  

        //단 건  
        val findMember1: Member? = queryFactory  
            .selectFrom(m)  
            .fetchOne()  

        //처음 한 건 조회  
        val (id, name, age, team) = queryFactory  
            .selectFrom(m)  
            .fetchFirst()  

        //페이징에서 사용  
        val results: QueryResults<Member> = queryFactory  
            .selectFrom(m)  
            .fetchResults()  

        //count 쿼리로 변경  
        val count = queryFactory  
            .selectFrom(m)  
            .fetchCount()  
    }  
}

JPQL이 제공하는 모든 검색 조건

and 메서드:
- 기능: 두 개의 조건을 AND 연산으로 결합합니다.
- 사용 예시: builder.and(condition1)


or 메서드:
- 기능: 두 개의 조건을 OR 연산으로 결합합니다.
- 사용 예시: builder.or(condition1)


not 메서드:
- 기능: 조건을 부정합니다.
- 사용 예시: builder.not(condition)


value 메서드:
- 기능: BooleanBuilder 객체를 불리언 조건으로 변환합니다.
- 사용 예시: val condition = builder.value


isNull 메서드:
- 기능: 주어진 필드가 NULL인지 확인하는 조건을 추가합니다.
- 사용 예시: builder.isNull(field)


isNotNull 메서드:
- 기능: 주어진 필드가 NULL이 아닌지 확인하는 조건을 추가합니다.
- 사용 예시: builder.isNotNull(field)


eq 메서드:
- 기능: 주어진 필드와 값이 같은지 확인하는 조건을 추가합니다.
- 사용 예시: builder.eq(field, value)


ne 메서드:
- 기능: 주어진 필드와 값이 다른지 확인하는 조건을 추가합니다.
- 사용 예시: builder.ne(field, value)


gt 메서드:
- 기능: 주어진 필드가 주어진 값보다 큰지 확인하는 조건을 추가합니다.
- 사용 예시: builder.gt(field, value)


lt 메서드:
- 기능: 주어진 필드가 주어진 값보다 작은지 확인하는 조건을 추가합니다.
- 사용 예시: builder.lt(field, value)


gte 메서드:
- 기능: 주어진 필드가 주어진 값보다 크거나 같은지 확인하는 조건을 추가합니다.
- 사용 예시: builder.gte(field, value)


lte 메서드:
- 기능: 주어진 필드가 주어진 값보다 작거나 같은지 확인하는 조건을 추가합니다.
- 사용 예시: builder.lte(field, value)


m.name.eq("member1")  
m.name.ne("member2")  
m.name.eq("member1").not()  

m.name.isNotNull  

m.age.`in`(10, 20)  
m.age.notIn(10, 20)  
m.age.between(10, 30)  

m.age.goe(30) // age >= 30  
m.age.gt(30) // age > 30  
m.age.loe(30) // age <= 30  
m.age.lt(30) // age < 30  

m.name.like("member%") // like 검색  
m.name.contains("member") // like %member% 검색  
m.name.startsWith("member") // like member% 검색

And 조건을 파라미터로 처리

where()에 파라미터로 검색조건을 추가하면 AND 조건이 추가된다.
이경우 null값은 무시 -> 메서드 추출을 활용해 동적 쿼리르 깔끔하게 만들수 있다.

/** @desc And 조건을 파라미터로 처리 */
@Test  
fun searchAndParam() {  
    val m: QMember = QMember("m")  

    val result: List<Member> = queryFactory  
        .selectFrom(m)  
        .where(m.name.eq("member1"))  
        .fetch()  

    assertThat(result.size).isEqualTo(1)  
}

결과 조회

fetch() : 리스트 조회

fetchOne() : 단건 조회

  • 결과가 없으면 Null
  • 결과가 둘 이상이면 NonUniqueResultException 발생

fetchFirst() : limit(1).fetchOne()

fetchResults() : 페이징 정보 포함, totle count 쿼리 추가 실행

fetchCount() : Count 쿼리로 변경해서 count 수 조회

/** @desc And 조건을 파라미터로 처리 */
@Test  
fun searchAndParam() {  
    val m: QMember = QMember("m")  

    val result: List<Member> = queryFactory  
        .selectFrom(m)  
        .where(m.name.eq("member1"))  
        .fetch()  

    assertThat(result.size).isEqualTo(1)  

    //List  
    val fetch: List<Member> = queryFactory  
        .selectFrom(m)  
        .fetch()  

    //단 건  
    val findMember1: Member? = queryFactory  
        .selectFrom(m)  
        .fetchOne()  

    //처음 한 건 조회  
    val (id, name, age, team) = queryFactory  
        .selectFrom(m)  
        .fetchFirst()  

    //페이징에서 사용  
    val results: QueryResults<Member> = queryFactory  
        .selectFrom(m)  
        .fetchResults()  

    //count 쿼리로 변경  
    val count = queryFactory  
        .selectFrom(m)  
        .fetchCount()  
}