在使用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" "[" "^" "|"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}')
扩展知识:jsonb_exists_any只支持字符串数组(text[])的检索,不支持integer、bigint等数值类型,在构建json数据结构的时候需要注意下。