报错如标题所示,为了不耽误时间先给解决思路再唠起源
在这里插入图片描述

根据自己多年的经验本以为就是mapper没有扫到的原因,这也是网上大多数给的意见,事实上通过我的研究原因多种多样,具体如下:


上下求索

排查复盘

  • 从报错日志中看是SqlSessionTemplate,没有顺利初始化导致
    在这里插入图片描述

  • 为了详细说明我们跟进去看看,是哪里初始化,注:以下就要分情况讨论了:
    哦对了,在说明情况之前有个基础共识:如果你的项目是新项目,确实要看看有没有把你的包扫描进去,一般来说有两个操作步骤:

    • 1. 通过配置文件指定:

      mybatis:
        mapper-locations: classpath*:mapper/**/*.xml
      

      PS:你如果使用了mybatis-starter【1.7+】,那这一步是省略的

    • 2. 通过@mapper指定扫描包范围:我习惯兜底遍历,这样保证一定没问题,牺牲了启动时间也还OK

      @MapperScan(“com.company.**.mapper”)

    • 3.??? 怎么还有第三,那还不因为是新创建的项目,引入mybatis-starter时,默认注入配置: DataSourceAutoConfiguration,一些图省事的童鞋,直接在配置里排除注入,实际上也把sqlSessionTemplate注入也一并排除了,这才是天坑呀。


当然了如果是运营一段时间的老项目,你加入了一些其他配置也会导致这个问题,那么我们就要好好看看究竟是哪个老六,我目前遇到了加了两种依赖导致这个问题:

在MyBatis基础之上,引入MyBatisPlus【我就是这种情况】
通过开头的报错堆栈,跟进排查发现sqlSessionTemplate 的初始化交给了MybatisPlusAutoConfiguration
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

这只是从底层往上追溯,不太有说服力,那么我们直接打开springboot 的debug = true【这才是本文灵魂所在】 查看注入依赖,验证我们的结论;
在这里插入图片描述
果然not match,那么大部分情况看到这里解决方案也就明了,看看后面具体的提示即便也就了然于胸
而我这里大差不差,因为引入了sharding-jdbc 和 dynamic-datasource 导致引入两个同类型的datasourcce bean, 又没有指定优先级造成无法正确注入

因此本方案下的解决思路便是结合sharding 和 多数据源,具体配置我就不粘贴了照着官网或者配置文件:DynamicDataSourceProperties看就行了

@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class})
public class DataSourceConfiguration {

    public static final String SHARDING_DATASOURCE = "sync-sharding";

    @Resource
    private DynamicDataSourceProperties dynamicDataSourceProperties;

    /**
     * shardingjdbc有四种数据源,需要根据业务注入不同的数据源
     *
     * <p>1. 未使用分片, 脱敏的名称(默认): shardingDataSource;
     * <p>2. 主从数据源: masterSlaveDataSource;
     * <p>3. 脱敏数据源:encryptDataSource;
     * <p>4. 影子数据源:shadowDataSource
     *
     * shardingjdbc默认就是shardingDataSource
     */
    @Lazy
    @Resource(name = "shardingDataSource")
    private DataSource shardingDataSource;

    @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider() {
        // 多数据源的map
        Map<String, DataSourceProperty> datasource = dynamicDataSourceProperties.getDatasource();
        // 接管sharding
        return  new AbstractDataSourceProvider() {
            @Override
            public Map<String, DataSource> loadDataSources() {
                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasource);
                dataSourceMap.put(SHARDING_DATASOURCE, shardingDataSource);
                return dataSourceMap;
            }
        };
    }


    @Primary // 关键
    @Bean
    public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
        DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();
        dynamicRoutingDataSource.setP6spy(dynamicDataSourceProperties.getP6spy());
        dynamicRoutingDataSource.setPrimary(dynamicDataSourceProperties.getPrimary());
        dynamicRoutingDataSource.setSeata(dynamicDataSourceProperties.getSeata());
        dynamicRoutingDataSource.setStrict(dynamicDataSourceProperties.getStrict());
        dynamicRoutingDataSource.setStrategy(dynamicDataSourceProperties.getStrategy());
        return dynamicRoutingDataSource;
    }
}


怒发冲冠

至此,对于解决思路有了清晰的认识,但起初因为惰性思考导致耗费了不少时间和精力,甚至一度怀疑自己能力
其实早在错误堆栈出现的时候,就应该本能直接从结果上遍历,但因为几年顺利的开发经验告诉我 就是包没有扫入或者其他可以直接从网上就能得到的答案:思维惰性害己呀

思维惰性可能让我们离解决问题的道路渐行渐远,比如我甚至重新用mybaits搭建项目,因为懒得配置数据库,直接在配置文件跳过DataSourceAutoConfiguration的注入,发现还是注入不到sqlSessionTemplate 导致直接失去信心,而这也是因为对网上答案深信不疑一个多小时才猛然发现。

有的时候自带的调试框架如debug=true 真的指路明灯,当你仔细阅读一下才恍然大悟。

勤于思考吧 童鞋们~ 吾当共勉

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐