问题背景:
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对象进行解析
扫描二维码关注公众号,回复: 13601647 查看本文章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: 配置问题