QueryDSL JPA: REGEXP 방법의 올 바른 사용 자세

8375 단어 kotlinQueryDSLJPA
상황 이 환원 되다.
나 는 지난 글 에서 데이터베이스 에 JSon 문자열 의 데 이 터 를 저장 해 야 한다 고 말 했다. 그리고 이 데 이 터 를 어떻게 검색 하 느 냐 가 다음 에 내 가 해결 해 야 할 문제 가 되 었 다. 다행히 이번에 검색 해 야 할 데 이 터 는 간단 한 성형 디지털 목록 일 뿐이다.정규 표현 식 을 쓰 면 지정 한 ID 에 따라 이 ID 를 포함 하 는 모든 JSon 문자열 을 가 져 올 수 있다 는 생각 이 들 었 습 니 다. 예 를 들 어 검색 목록 에 ID 가 1 인 기록 이 포함 되 어 있 습 니 다.
select * from s_dep where parent_list_json regexp '[\[,]1[,\]]'

네 이 티 브 SQL 방식 으로 이러한 조 회 를 실현 하 는 것 을 알 게 된 이상 Query DSL + JPA 프레임 워 크 에서 이러한 조회 조건 을 조합 하면 됩 니 다.
class DepSearchKey : SearchKey<DepEntity> {
	//      
    private val dep = QDepEntity.depEntity
    //       
    private val baseCondition = dep.isNotNull

    /**
     *     
     */
    var name: String? = null
    /**
     *   id
     */
    var parentId: Long? = null
    /**
     *   id      
     */
    var parentListContains: Long? = null

    override val searchKey: BooleanExpression
        get() {
            var condition = baseCondition
            name?.also { condition = condition.and(dep.name.eq(it)) }
            parentId?.also { condition = condition.and(dep.parentId.eq(it)) }
            //     id        
			parentListContains?.also { 
				condition = condition.and(dep.parentListJson.matches("[\\[,]${it}[,\\]]")) 
			}
            return condition
        }
}


그러나 안 타 깝 게 도 이런 표기 법 은 정확하게 집행 되 지 못 하고 실행 할 때 오 류 를 보고 할 수 있다.
com.querydsl.core.QueryException: '[\[,]1[,\]]' can't be converted to like form
	at com.querydsl.core.types.ExpressionUtils.regexToLike(ExpressionUtils.java:676)
	at com.querydsl.jpa.JPQLSerializer.visitOperation(JPQLSerializer.java:417)
	at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:231)
	at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:31)
	at com.querydsl.core.types.OperationImpl.accept(OperationImpl.java:83)
	at com.querydsl.core.support.SerializerBase.handle(SerializerBase.java:92)
	at com.querydsl.core.support.SerializerBase.visitOperation(SerializerBase.java:267)
	at com.querydsl.jpa.JPQLSerializer.visitOperation(JPQLSerializer.java:437)
	at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:231)
	at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:31)
	at com.querydsl.core.types.OperationImpl.accept(OperationImpl.java:83)
	at com.querydsl.core.support.SerializerBase.handle(SerializerBase.java:92)
	......

문제 탐구
이 이상 로그 에서 얻 을 수 있 는 정 보 는 QueryDSL 에서 지정 한 정규 표현 식 을 Like 형식 으로 변환 할 수 없습니다.이 말의 뜻 은 알 아 볼 수 있 지만 왜 이런 문제 가 발생 했 는 지 모르겠다.그래서 나 는 다음 공식 문서 에서 StringPath.matches() 방법 에 대한 설명 을 찾 아 보 았 다.
Create a this.matches(regex) expression Return true if this String matches the given regular expression Some implementations such as Querydsl JPA will try to convert a regex expression into like form and will throw an Exception when this fails
이 묘사 에서 중점 적 인 부분 은 StringPath.matches() 이라는 방법 이 querydsl-jpa 과 같은 실현 류 에서 정규 표현 식 을 SQL like 의 형식 (즉 _ % 이라는 두 가지 기호 만 있 음) 으로 바 꾸 려 고 시도 하 는데 이런 전환 이 실패 하면 이상 을 던 질 것 이다.
그렇다면 우 리 는 StringPath.matches() 방법 을 사용 하여 JPA 와 연합 한 상황 에서 정규 매 칭 을 실현 할 수 없 기 때문에 나 는 생각 을 바 꾸 었 다. SQL 을 호출 하 는 REGEXP_LIKE() 방법 은 같은 검색 효 과 를 실현 할 수 있 기 때문에 Query DSL 에서 SQL 방법 을 호출 하면 이런 조 회 를 실현 할 수 있다.
해결 방안Expressions.booleanTemplate() 방법 을 사용 하면 SQL 방법 에 대한 호출 을 실현 할 수 있 습 니 다.
//     id        
parentListContains?.also { condition = condition.and(
   Expressions.booleanTemplate(
        "regexp_like({0}, {1}) = true"
        , dep.parentListJson
        , "[\\[,]${it}[,\\]]"
    )
)}

좋은 웹페이지 즐겨찾기