Postgres和JOOQ的不区分大小写的正则表达式?

时间:2017-07-07 04:53:41

标签: java sql jooq

我目前在JOOQ中使用此代码:

Condition condition = DSL.trueCondition();
if( isNotBlank(email) ){
  condition = condition.and(APP_USER.EMAIL.likeRegex(email));
}

最终发布Postgres特定的SQL,它在DB中执行正则表达式匹配:

app_user.email ~ '{email regex}'

是否可以让JOOQ发布case insensitive版本:app_user.email ~* '{email regex}'

我目前的解决方法是使用此代码:

if( isNotBlank(email) ){
  condition = condition.and(
    APP_USER.EMAIL.lower().likeRegex(email.toLowerCase()) );
}

1 个答案:

答案 0 :(得分:4)

如果jOOQ API缺少特定于供应商的功能,答案是"plain SQL"。在你的情况下,只需写下:

PostgreSQL特定的解决方案

Condition condition = DSL.trueCondition();
if( isNotBlank(email) ){
  condition = condition.and("{0} ~* {1}", APP_USER.EMAIL, DSL.val(email));
}

方法Condition.and(String, QueryPart...)只是通过DSL.condition(String, QueryPart...)创建显式纯SQL Condition的便利:

Condition condition = DSL.trueCondition();
if( isNotBlank(email) ){
  condition = condition.and(DSL.condition("{0} ~* {1}", APP_USER.EMAIL, DSL.val(email)));
}

与供应商无关的解决方案

如果您想与供应商无关,则必须将上述代码包装在您自己的实用程序中,并使用CustomCondition

public static Condition caseInsensitiveLikeRegex(Field<String> field, String regex) {
    return new CustomCondition() {
        @Override
        public void accept(Context<?> ctx) {
            if (ctx.family() == POSTGRES)
                ctx.visit(DSL.condition("{0} ~* {1}", field, DSL.val(regex));
            else
                ctx.visit(field.lower().likeRegex(regex.toLowerCase()));
        }
    }
}

regex.toLowerCase()调用当然不是100%正确,因为它会降低正则表达式内容以及转义模式(例如\B反斜杠的情况),但是你得到了这个想法