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正常使用。

总结

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

相关文章

  • 升级IDEA后Lombok不能使用的解决方法

    升级IDEA后Lombok不能使用的解决方法

    最近看到提示IDEA提示升级,寻思已经有好久没有升过级了。升级完毕重启之后,突然发现好多错误,本文就来介绍一下如何解决,感兴趣的可以了解一下
    2021-07-07
  • jenkins安装及其配置笔记

    jenkins安装及其配置笔记

    这篇文章主要介绍了jenkins安装及其配置笔记,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • 10种java数组合并的常用方法总结

    10种java数组合并的常用方法总结

    在Java中,合并(或连接)数组是常见的任务,这篇文章主要为大家整理了10个java中常用的数组合并方法,文中的示例代码简洁易懂,需要的小伙伴可以参考下
    2023-12-12
  • 常见的排序算法,一篇就够了

    常见的排序算法,一篇就够了

    这篇文章主要介绍了一些常用排序算法整理,插入排序算法、直接插入排序、希尔排序、选择排序、冒泡排序等排序,需要的朋友可以参考下
    2021-07-07
  • Java redisTemplate阻塞式处理消息队列

    Java redisTemplate阻塞式处理消息队列

    用redis中的List可以实现队列,这样可以用来做消息处理和任务调度的队列。因此,本文将主要为大家介绍如何利用redisTemplate处理消息队列,感兴趣的小伙伴可以了解一下
    2021-12-12
  • java基础之数组常用操作总结(必看篇)

    java基础之数组常用操作总结(必看篇)

    下面小编就为大家带来一篇java基础之数组常用操作总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Java线程的控制详解

    Java线程的控制详解

    这篇文章主要介绍了Java中的join线程、后台线程、线程睡眠、线程让步以及线程的优先级,非常的详细,希望能对大家有所帮助
    2014-10-10
  • 在java中使用dom4j解析xml(示例代码)

    在java中使用dom4j解析xml(示例代码)

    鉴于目前的趋势,我们这里来讲讲Dom4j的基本用法,不涉及递归等复杂操作。Dom4j的用法很多,官网上的示例有那么点儿晦涩,这里就不写了
    2013-10-10
  • 教你使用idea搭建ssm详细教程(Spring+Spring Mvc+Mybatis)

    教你使用idea搭建ssm详细教程(Spring+Spring Mvc+Mybatis)

    今天教大家使用idea搭建ssm详细教程(Spring+Spring Mvc+Mybatis),文中有非常详细的图文介绍及代码示例,对正在学习使用idea的小伙伴很有帮助,需要的朋友可以参考下
    2021-05-05
  • Java数据结构之链表的概念及结构

    Java数据结构之链表的概念及结构

    这篇文章主要介绍了数据链表的概念及结构,链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。想进一步了解的同学,可以参考阅读本文
    2023-04-04

最新评论