這個問題昨晚花了很長時間去查資料,其實網上的方法已有很多,但都解決不了。於是從spring初始化mybatis開始看起,發現程序不是沒有掃描到mybatis-plus配置,而是壓根沒有去掃描。為什么呢?
因為:SessionFactoryBean是自定義的,不是spring自動注入的!
然后又會有個問題,不是有@MapperScan么?怎么就沒掃描xml文件呢?通過斷點發現,mybatis-locations這個匹配是由sessionFactoryBean去配置的,@MapperScan掃描的時候,會掃描mapper類包,然后從sessionFactoryBean中取xml的匹配,然而,自定義的SqlSession並沒有去設置mybatisLocation這個參數,這時候就會當沒xml文件處理。在執行方法的時候,mybatis需要去找statement,當然就找不到了。
所以解決問題的辦法也很簡單,有三種解決方式
1. 用自動注入的sessionFactoryBean
2. 手動設置sessionFactoryBean.setMybatisLocation : new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mapper/*.xml")
3.把xml文件放到mapper同級目錄下,這個參考代碼,當沒有設置xml路徑時,會在當前類的同級路徑下去找xml文件,這樣找到也可以。
private void loadXmlResource() { // Spring may not know the real resource name so we check a flag // to prevent loading again a resource twice // this flag is set at XMLMapperBuilder#bindMapperForNamespace if (!configuration.isResourceLoaded("namespace:" + type.getName())) { String xmlResource = type.getName().replace('.', '/') + ".xml"; // #1347 InputStream inputStream = type.getResourceAsStream("/" + xmlResource); if (inputStream == null) { // Search XML mapper that is not in the module but in the classpath. try { inputStream = Resources.getResourceAsStream(type.getClassLoader(), xmlResource); } catch (IOException e2) { // ignore, resource is not required } } if (inputStream != null) { XMLMapperBuilder xmlParser = new XMLMapperBuilder(inputStream, assistant.getConfiguration(), xmlResource, configuration.getSqlFragments(), type.getName()); xmlParser.parse(); } } }