问题描述
在使用mybatis-plus的过程中,有一个jsonb字段使用了jsonb_exists_any (field_name, text[])作为where条件查询,执行sql如下:
SELECT * FROM table_name
WHERE jsonb_exists_any (field_name, ARRAY['110544709344', '12564892357'])
上面的sql在navicat中执行正常,所以sql没有问题,但是在mybatis-plus的xml文件中使用就会报错,异常信息如下:
Caused by: net.sf.jsqlparser.JSQLParserException: Encountered unexpected token: "(" "("
at line 4, column 33.
Was expecting one of:
"&"
"&&"
"::"
";"
"<<"
">>"
"AND"
"COLLATE"
"CONNECT"
"EXCEPT"
"FOR"
"GROUP"
"HAVING"
"INTERSECT"
"MINUS"
"OR"
"ORDER"
"START"
"UNION"
"["
"^"
"|"
<EOF>
at net.sf.jsqlparser.parser.CCJSqlParserUtil.parseStatements(CCJSqlParserUtil.java:188) ~[jsqlparser-4.0.1-SNAPSHOT.jar:na]
at net.sf.jsqlparser.parser.CCJSqlParserUtil.parseStatements(CCJSqlParserUtil.java:176) ~[jsqlparser-4.0.1-SNAPSHOT.jar:na]
at com.baomidou.mybatisplus.core.parser.AbstractJsqlParser.parser(AbstractJsqlParser.java:62) ~[mybatis-plus-core-3.4.2.jar:3.4.2]
... 139 common frames omitted
解决方案
方案1:在网上看了很多解决方式,说是因为MyBatis_Plus框架中,有多租户的功能(也就是通过sql拦截器注入租户信息),MP会进行数据权限的过滤导致的,可以使用下面的注解(+配置)解决:
// Mybatis-plus 3.4.x以前的的版本
@SqlParser(filter = true)
// 如果Mybatis-plus版本是3.1.1以上的,直接添加@SqlParser注解即可,但如果是3.1.1以下版本,还需要在资源文件添加如下配置:
# 开启 SQL 解析缓存注解生效
mybatis-plus:
global-config:
sql-parser-cache: true
// Mybatis-plus 3.4.x之后的版本,@SqlParser已过期,可以直接使用下面的注解代替
@InterceptorIgnore(tenantLine = "true")
方案2: 由于我们的系统本身就需要多租户功能,所以无法通过上面的方式解决,在网上又找了下,看到了通过升级com.github.jsqlparser:jsqlparser sql解析器,解决依赖冲突的方案来解决:
https://blog.csdn.net/xiaozhang_man/article/details/127193780
最终方案: 由于不敢随便升级依赖包,怕引入新的问题,我最终的解决方案是不使用array函数,避开jsqlparser不支持某些关键字或函数,修改后的sql如下:
SELECT * FROM table_name
WHERE jsonb_exists_any (field_name, '{110544709344, 12564892357}')文章来源:https://uudwc.com/A/vmWwR
扩展知识:jsonb_exists_any只支持字符串数组(text[])的检索,不支持integer、bigint等数值类型,在构建json数据结构的时候需要注意下。文章来源地址https://uudwc.com/A/vmWwR