mybatis 启动报错 分析

问题背景:

nacos 注册服务中心,在新的配置分组(crm)启动了一个微服务
默认分组启动正常,通过打断点发现: 1.新的分组crm启动的报错点,在默认分组启动的时候 并未执行

也就是 默认分组启动不会走

initNodeHandlerMap() 方法

mybatis 启动报错信息

Caused by: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. The XML location is 'file [D:\IdeaProject\wk_crm_c_backend\c-crm\target\classes\mapper\xml\CallRecordMapper.xml]'. Cause: org.apache.ibatis.builder.BuilderException: Unknown element <for> in SQL statement.
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:122)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:94)
	at com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean.buildSqlSessionFactory(MybatisSqlSessionFactoryBean.java:593)
	... 70 common frames omitted
Caused by: org.apache.ibatis.builder.BuilderException: Unknown element <for> in SQL statement.
	at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseDynamicTags(XMLScriptBuilder.java:95)
	at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseScriptNode(XMLScriptBuilder.java:67)
	at org.apache.ibatis.scripting.xmltags.XMLLanguageDriver.createSqlSource(XMLLanguageDriver.java:44)
	at org.apache.ibatis.builder.xml.XMLStatementBuilder.parseStatementNode(XMLStatementBuilder.java:96)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildStatementFromContext(XMLMapperBuilder.java:137)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildStatementFromContext(XMLMapperBuilder.java:130)
	at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:120)
	... 72 common frames omitted

分析 代码

 private void initNodeHandlerMap() {
    
    
    nodeHandlerMap.put("trim", new TrimHandler());
    nodeHandlerMap.put("where", new WhereHandler());
    nodeHandlerMap.put("set", new SetHandler());
    nodeHandlerMap.put("foreach", new ForEachHandler());
    nodeHandlerMap.put("if", new IfHandler());
    nodeHandlerMap.put("choose", new ChooseHandler());
    nodeHandlerMap.put("when", new IfHandler());
    nodeHandlerMap.put("otherwise", new OtherwiseHandler());
    nodeHandlerMap.put("bind", new BindHandler());
  }

XMLScriptBuilder 初始化的时候 map 中没有初始化for 标签

但是 for标签在mybatis 是生效的,

简单的笨方法 : 把 for 标签 全部替换为 foreach

接着 分析下为什么会遇到这样的问题
首先参考总资料 https://www.cnblogs.com/linjisong/p/6039949.html
发现 了

单个SqlMapper.xml文件的解析入口是SqlSessionFactoryBean的doParseSqlMapperResource()方法,在这个方法中,自动侦测是DTD还是XSD,然后分两条并行路线分别解析:

1、DTD模式:创建XMLMapperBuilder对象进行解析

2、XSD模式:根据ini配置文件,找到sqlmapper命名空间的处理器SchemaSqlMapperNamespaceParser,该解析器将具体的解析工作委托给SchemaSqlMapperParserDelegate类。

进一步查找资料:

发现mybatis 支持 自定义节点,

参考资料:https://juejin.cn/post/6854573216359415822

但是这个微服务并没有这样的逻辑。

总结

问题发生的根源还是在于nacos 配置文件的差异 ,导致了服务启动的时候数据源初始化逻辑不同,进而导致mybatis 的标签报错

确认配置信息

mybatis-plus:
  configuration:
    default-scripting-language: com.vd.canary.core.crm.mybatis.MybatisXMLDriver
    call-setters-on-nulls: true
  mapper-locations: classpath:/mapper/xml/*.xml

default-scripting-language: 配置问题

猜你喜欢

转载自blog.csdn.net/keep_learn/article/details/117824351