我们的项目是多租户的,所以同事自定义了MyBatis的拦截器,在该拦截器中获取请求头中传递过来的租户Id,然后注入到所有的SQL中,其具体实现方式我暂时没有研究(我暂时没有计划去系统研究MyBatis-Plus)。
问题在于使用该方案后,会导致如下的代码无法正常执行:
|
|
|
|
具体报错如下:
Caused by: net.sf.jsqlparser.parser.ParseException: Encountered unexpected token: "->>" "->>"
at line 4, column 39.
Was expecting one of:
"&"
"&&"
")"
"::"
"<<"
">>"
"AND"
"["
"^"
"|"
at net.sf.jsqlparser.parser.CCJSqlParser.generateParseException(CCJSqlParser.java:25031)
at net.sf.jsqlparser.parser.CCJSqlParser.jj_consume_token(CCJSqlParser.java:24875)
at net.sf.jsqlparser.parser.CCJSqlParser.AndExpression(CCJSqlParser.java:8062)
at net.sf.jsqlparser.parser.CCJSqlParser.OrExpression(CCJSqlParser.java:8008)
at net.sf.jsqlparser.parser.CCJSqlParser.AndExpression(CCJSqlParser.java:8134)
at net.sf.jsqlparser.parser.CCJSqlParser.OrExpression(CCJSqlParser.java:8008)
at net.sf.jsqlparser.parser.CCJSqlParser.Expression(CCJSqlParser.java:7979)
at net.sf.jsqlparser.parser.CCJSqlParser.WhereClause(CCJSqlParser.java:6922)
at net.sf.jsqlparser.parser.CCJSqlParser.PlainSelect(CCJSqlParser.java:4075)
at net.sf.jsqlparser.parser.CCJSqlParser.SetOperationList(CCJSqlParser.java:4264)
at net.sf.jsqlparser.parser.CCJSqlParser.SelectBody(CCJSqlParser.java:3923)
at net.sf.jsqlparser.parser.CCJSqlParser.Select(CCJSqlParser.java:3916)
at net.sf.jsqlparser.parser.CCJSqlParser.SingleStatement(CCJSqlParser.java:130)
at net.sf.jsqlparser.parser.CCJSqlParser.Statement(CCJSqlParser.java:81)
at net.sf.jsqlparser.parser.CCJSqlParserUtil.parse(CCJSqlParserUtil.java:63)
... 84 more
该问题其实之前没出现过的这个问题的,该如何处理呢,将ProjectMapper.java改为如下内容:
|
|
解决这个问题花费了我整整一个上午的时间,实际上我根本不需要花费这么长时间解决这个问题,因为我一开始就尝试了正确的方案,结果因为其他的Bug,导致我认为自己的方案有问题。对解决这个问题的过程进行复盘,有如下问题:
- 项目做如此底层的调整,没有通知到所有的开发人员。
- 项目做了调整后,开发却忘记提交相关的配置文件,导致我这边无论如何尝试,都是错误的。
因为注入了自定义拦截器,导致pg的->>
无法不可用,同事使用的解决方案是使用${operation}
将->>
作为一个参数传入到SQL中,这样就可以避免JSQLParser对此的解析。我觉得这是一种不优雅的写法,所以我还是比较推荐上面的写法。
解决此问题的过程中,我尝试了如下的方案:
- 升级和降级JSQLParser
- 使用InterceptorIgnore注解
- 使用SQLParser注解
- 使用bind标签
- 使用参数传递
->>
操作
我觉得可能有更优雅的方案,比如在开发注解时下点功夫,但是暂时没有精力研究相关问题。