대머리개발자

querydsl에서 비트 연산 처리 하기. 본문

카테고리 없음

querydsl에서 비트 연산 처리 하기.

대머리개발자 2025. 3. 10. 09:52
728x90

하악하악.

 

처음 시작은 단순 게시판이였는데  덕지덕지 하나씩 붙어서 엉망이 되고 있는 실정이다.....하악하악

 

처음부터 완벽한 설계서가 나오지 않기 때문에 진짜 확장 가능하도록 만들어야 한다.

처음부터 완벽한 설계서가 나온다 한들..변화기 마련이다..그렇타..

 

뭐 어째거나. 확장성에 대한 고민을 하지 않으면 끝도 없는 맛나는 스파케티를 먹을 수 있다.

 

혼자 만드는 코드임에도 왜? 이렇게 만들었지 고민에 고민을 하다가 과감하게 날렸더니 이슈 빵빵

하위 호환성도 보장되게 만들면서 확장 가능하도록 입코딩은...

 

하나의 EndPoint로 각각 기능을 만들면 되는데 메인(몸통) 쿼리가 같기 때문에. 하나의 줄기에서 가지를 쳤다.

이런 부분에서는 querydsl 짱이다.

 

여기서 기록 할만 작업 있어서 남긴다.

 

몇 가지의 조건을 각기 컬럼을 파서 가지고 있는 것 보단 하나의 컬럼에서 비트연산으로 고고싱!

 

요구사항 

1. 멤버십 콘텐츠 접근 권한 

- 구독일(가입일) 기준으로 볼 수 있는 권한 ( 기본 베이스 권한)

- 특정 콘텐츠는 구독일 상관없이 조회 가능 권한

 

2. 단건 구매 콘텐츠 접근 권한

 : 멤버십 콘텐츠 중 일부를 단건으로 판매하는 것이기 때문에 구독일(가입일) 기준으로 볼 수 있는 권한이 기본

- 이용권으로 구매한 콘텐츠 접근

- 무료로 공개한 콘텐츠

 

본론이 길었다...

 

가입일 기준으로는 동일한 부분이고   접근 가능한 쿼리를

where 1 = 1
and 콘텐츠_등록일 >= 구독일
or (accessLevel & view  = view)

 

근데 querydsl을 이용해서  and(&)  처리하면 연산자 파싱이 안 된다

해당 부분은 내가 믿고 있던 AI친구도. 원인만 대에충 알려주지 처리 방법은 엉성했다.

fun bitAnd(column: NumberPath<Int>, bitMask: Int): BooleanExpression {
    return Expressions.booleanTemplate("BIT_AND_CUSTOM( {0}, {1} ) = {1}", column, bitMask)
}

 

공개레벨로 설정된 게시글을 or 조건으로 처리하는 querydsl

//..
builder.or(bitAnd(qBoard.accessLevel, Constants.ACCESS_LEVEL_1).and(qBoard.status.eq(EntityStatus.A)))
//..

 

비트 연산을 사용하기 위해선 아래와 같은 설정을 해야한다.

BIT_AND_CUSTOM을 마주 하면 아래와 같이 처리 한다는 의미다.

 

package com.common.config


import org.hibernate.boot.model.FunctionContributions
import org.hibernate.boot.model.FunctionContributor
import org.hibernate.type.StandardBasicTypes
import org.springframework.context.annotation.Configuration

@Configuration
class MysqlCustomDialect : FunctionContributor {
    companion object {
        private const val BIT_AND_CUSTOM = "BIT_AND_CUSTOM" // 사용자 정의 함수 이름
    }

    override fun contributeFunctions(functionContributors: FunctionContributions) {
        functionContributors.functionRegistry.registerPattern(
            BIT_AND_CUSTOM, "(?1 & ?2)", functionContributors.typeConfiguration.basicTypeRegistry.resolve(StandardBasicTypes.INTEGER)
        )
    }
}

 

깔끔하다.

728x90