简体   繁体   English

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

[英]Case insensitive regex with Postgres and JOOQ?

I currently use this code with JOOQ: 我目前在JOOQ中使用此代码:

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

That ends up issuing Postgres specific SQL that does the regex match in the DB: 最终发布Postgres特定的SQL,在数据库中进行正则表达式匹配:

app_user.email ~ '{email regex}'

Is it possible to get JOOQ to issue the case insensitive version: app_user.email ~* '{email regex}' ? 是否有可能让JOOQ发布不区分大小写的版本: app_user.email ~* '{email regex}'


My current workaround is to use this code: 我目前的解决方法是使用此代码:

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

If ever the jOOQ API is missing vendor-specific functionality, the answer is "plain SQL" . 如果jOOQ API缺少特定于供应商的功能,答案是“纯SQL” In your case, simply write this: 在你的情况下,只需写下:

PostgreSQL-specific solution PostgreSQL特定的解决方案

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

The method Condition.and(String, QueryPart...) is just convenience for creating an explicit plain SQL Condition through DSL.condition(String, QueryPart...) : 方法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)));
}

Vendor-agnostic solution 与供应商无关的解决方案

If you want to be vendor-agnostic, you'd have to wrap the above code in your own utility and resort to using a CustomCondition 如果您想与供应商无关,则必须将上述代码包装在您自己的实用程序中并使用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()));
        }
    }
}

The regex.toLowerCase() call is not 100% correct, of course, as it lower cases both the regex content, as well as the escaped patterns, such as \\B for backslash, but you get the idea. 当然, regex.toLowerCase()调用不是100%正确,因为它会降低正则表达式内容以及转义模式(例如反斜杠的\\B ,但您可以理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM