sql于navicat中能运行在mybatis中不能运行的解决方案

 更新时间:2024年01月27日 10:30:58   作者:_0.78  
这篇文章主要介绍了sql于navicat中能运行在mybatis中不能运行的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

其异常信息

如下:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:

Error querying database. Cause: com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: Failed to process, please exclude the tableName or statementId.

在本条sql中,于navicat中是可以正常运行的,但是在mybatisplus中是不可以正常使用的

SELECT
	claim_key,
	claim_no,
	occur_time,
	amnt,
	b_name,
	city_branch_code,
	town_branch_code,
	cntr_no,
	opsn_name,
	opsn_id_no,
	rcpt_amnt,
	occur_result_code,
	accept_clerk_code,
	accept_branch_no,
	proc_clerk_no,
	proc_clerk_branch,
	chk_clerk_no,
	pol_code,
	claim_date,
	close_date,
	accept_channel,
	hospital_name,
	occur_1cls_code,
	lp_extracted 
FROM
	compensation_case 
WHERE
	stamp & gt;= DATE_FORMAT( "2021-02-08 00:00:00", 'yyyy-MM-dd %H:%m:%s' ) 
AND stamp & lt;= DATE_FORMAT( "2023-02-08 00:00:00", 'yyyy-MM-dd %H:%m:%s' ) 
AND lp_extracted = 0 
AND claim_proc_stat = 'E' 
AND pol_code IN ( 'DDD', 'DDE', '975' ) = 0

后经排查,有两个解决方案

1、使用注解 @SqlParser(filter = true) 就可以解决问题,其实现原理为略过 mybatis plus的SQL解析过滤,直接执行sql,这个效果跟在navicat执行sql的效果是一样的。

2、修改sql语句,将in () = 0 修改为 not in,这样子的话就可以在mybatis plus中就可以正常运行了。

其具体的出错原因还需要进行debug查询。

在debug的过程中,看到了mybatisplus的解析处理器中如下代码:

public abstract class AbstractSqlParserHandler{
    /**
     * 拦截 SQL 解析执行
     */
    protected void sqlParser(MetaObject metaObject) {
        //
        // @SqlParser(filter = true) 跳过该方法解析
        if (SqlParserHelper.getSqlParserInfo(metaObject)) {
            return;
        }
        //
    }
}

可以看到如果加上了@SqlParser(filter = true)注解的话,就会跳过SQL解析。

在底层sql解析中,可以看到sql在where解析的时候,抛出了异常,根据特殊符号进行解析

net.sf.jsqlparser.parser.ParseException: Encountered unexpected token: "=" "="
    at line 33, column 51.

Was expecting one of:

    "&&"
    ";"
    "AND"
    "CONNECT"
    "EXCEPT"
    "FOR"
    "GROUP"
    "HAVING"
    "INTERSECT"
    "MINUS"
    "ORDER"
    "START"
    "UNION"
    <EOF>

特殊符号如下

"&&"
";"
"AND"
"CONNECT"
"EXCEPT"
"FOR"
"GROUP"
"HAVING"
"INTERSECT"
"MINUS"
"ORDER"
"START"
"UNION"

在解析sql的时候,对于如下sql是这么解析的

AND pol_code IN ( 'DDD', 'DDE', '975' ) = 0

根据IN解析之后,认为下面这条SQL

AND pol_code IN ( 'DDD', 'DDE', '975' )

解析完成之后是一个完整的条件语句了。

那么这个条件语句它后面希望读取到的字符会期望是特殊符号

"&&"
";"
"AND"
"CONNECT"
"EXCEPT"
"FOR"
"GROUP"
"HAVING"
"INTERSECT"
"MINUS"
"ORDER"
"START"
"UNION"

但是由于本条SQL在

AND pol_code IN ( 'DDD', 'DDE', '975' )

之后提供的是 =

AND pol_code IN ( 'DDD', 'DDE', '975' ) = 0 

它不是mybatis plus所期望特俗字符中的其中一个,所以抛了异常,抛出异常的翻译如下:

net.sf.jsqlparser.parser.ParseException: Encountered unexpected token: "=" "="
    at line 33, column 51.

Was expecting one of:
    "&&"
    ";"
    "AND"
    "CONNECT"
    "EXCEPT"
    "FOR"
    "GROUP"
    "HAVING"
    "INTERSECT"
    "MINUS"
    "ORDER"
    "START"
    "UNION"
---------------------------------------------------------------------------------

在第 33 行第 51 列遇到意外标记:“=”“=”。期待以下之一:
    "&&"
    ";"
    "AND"
    "CONNECT"
    "EXCEPT"
    "FOR"
    "GROUP"
    "HAVING"
    "INTERSECT"
    "MINUS"
    "ORDER"
    "START"
    "UNION"

故解决该问题的办法有三种:

1、添加注解@SqlParser(filter = true),那么跳过mybatis的sql解析,直接就可以运行sql语句;

2、修改sql,将sql的 in () = 0 修改为 not in ();

3、修改源码。

综合考虑,选择第二种做法,将sql修改为如下

SELECT
	claim_key,
	claim_no,
	occur_time,
	amnt,
	b_name,
	city_branch_code,
	town_branch_code,
	cntr_no,
	opsn_name,
	opsn_id_no,
	rcpt_amnt,
	occur_result_code,
	accept_clerk_code,
	accept_branch_no,
	proc_clerk_no,
	proc_clerk_branch,
	chk_clerk_no,
	pol_code,
	claim_date,
	close_date,
	accept_channel,
	hospital_name,
	occur_1cls_code,
	lp_extracted 
FROM
	compensation_case 
WHERE
	stamp & gt;= DATE_FORMAT( "2021-02-08 00:00:00", 'yyyy-MM-dd %H:%m:%s' ) 
AND stamp & lt;= DATE_FORMAT( "2023-02-08 00:00:00", 'yyyy-MM-dd %H:%m:%s' ) 
AND lp_extracted = 0 
AND claim_proc_stat = 'E' 
AND pol_code NOT IN ( 'DDD', 'DDE', '975' )

修改之后重新运行,SQL正常使用。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • IDEA2021常用优化设置步骤图解

    IDEA2021常用优化设置步骤图解

    本文分步骤给大家讲解IDEA2021常用优化设置技巧,非常不错,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-09-09
  • Java Web中ServletContext对象详解与应用

    Java Web中ServletContext对象详解与应用

    ServletContext是一个容器,可以用来存放变量,供一个web项目中多个Servlet共享,下面这篇文章主要给大家介绍了关于Java Web中ServletContext对象详解与应用的相关资料,需要的朋友可以参考下
    2023-04-04
  • 详解MyBatis自定义Plugin插件

    详解MyBatis自定义Plugin插件

    这篇文章主要介绍了MyBatis自定义Plugin插件的相关知识,实现方法也很简单,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可,需要的朋友可以参考下
    2018-06-06
  • Java项目如何打包成Jar的实现步骤

    Java项目如何打包成Jar的实现步骤

    一般情况下我们都是使用Java项目直接部署发布,有时需要我们将写好的项目打成jar包,方便后期调用,本文主要介绍了Java项目如何打包成Jar,感兴趣的可以了解一下
    2023-11-11
  • Java编程调用微信分享功能示例

    Java编程调用微信分享功能示例

    这篇文章主要介绍了Java编程调用微信分享功能,结合实例形式分析了java微信分享功能接口的定义与调用相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • MyBatis Mapper接受参数的四种方式代码解析

    MyBatis Mapper接受参数的四种方式代码解析

    这篇文章主要介绍了MyBatis Mapper接受参数的四种方式代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Spring Boot整合Mybatis并完成CRUD操作的实现示例

    Spring Boot整合Mybatis并完成CRUD操作的实现示例

    这篇文章主要介绍了Spring Boot整合Mybatis并完成CRUD操作的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • java之使用多线程代替for循环(解决主线程提前结束问题)

    java之使用多线程代替for循环(解决主线程提前结束问题)

    这篇文章主要介绍了java之使用多线程代替for循环(解决主线程提前结束问题),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Java利用线程工厂监控线程池的实现示例

    Java利用线程工厂监控线程池的实现示例

    这篇文章主要介绍了Java利用线程工厂监控线程池的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Autowired的注入过程源码解析

    Autowired的注入过程源码解析

    这篇文章主要为大家介绍了Autowired的注入过程源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09

最新评论