首先探究此问题并无什么实际意义,纯属是个人好奇使然,也顺带熟悉了一下Springboot 数据库连接的相关问题,本人纯小白说的不对的地方恳请大佬指正!!
关于HikariDataSource (null)的误解
问题的发现
@Value("${mybatis-plus.mapper-locations}")private String[] mapperLocationPatterns;@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();factory.setDataSource(dataSource);factory.setMapperLocations();ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();List<Resource> resources = new ArrayList<>();for (String pattern : mapperLocationPatterns) {Collections.addAll(resources, resolver.getResources(pattern.trim()));}factory.setMapperLocations(resources.toArray(new Resource[0]));return factory.getObject();}
上图是自己手写的 sqlSessionFactory 然后调试过程中,在读取数据源的时候意外发现
dataSource = HikariDataSource (null) 第一眼我就被误解了误以为数据源映射失败了所以传了个空值,可是定睛一瞧却发现它实际上是创建成功了的,对象属性一个没少,只是它的名字里有个null
接下来就来谈谈这个容易误导人的null 到底说的是什么
首先讲解这个问题前要清楚,自动配置类往往在我们自己定义的@Configuration类之前先创建bean 于是根据这个我们很容易找到 dataSouce 实际上是依赖于 Hikari 创建的(关于Hikari知道他是个jdbc连接池就行,把它看作Druid也行,他是Springboot2.0以后默认的连接池)
于是我们可以在这个类(DataSourceConfiguration.class)里面找到 Hikari 下面的dataSource方法如下图
进一步的我们跳到 HikariDataSource 类里面继续找,感觉已经离目标很近了
还记得dataSource = HikariDataSource (null) 他是这么显示的,那么可以看出是他的类名叫这个于是锁定 toString()方法
终于找到了, 很显然为null的就是 这个pool 那么这个poll 是什么呢它为什么会显示null呢,继续寻找生成poll的方法于是
也就是说在Bean 加载过程中数据库只不过是把相关配置加载到了DataSource 但实际上并没有进行数据库连接 在项目正式启动完毕后 才向数据库发起第一次请求,并给他赋了初始值
可以看到此时括号内就不是null 而是数据库连接池的名字了,那么通过这个连接池也就可以查询到当前数据库的状态,比如当前连接数等等
当然你要是不想让他叫这个默认的名字也可以在配置文件中自己起一个比如“hhh”
总结一下
在spring创建dataSource bean 的时候只是将相关配置载入进去但并没有实施数据库连接(懒加载用来节省资源)因此这个时候 呈现的是一个没有数据库连接池的 dataSource (null)在项目全部加载完以后 再创建数据库连接池并发起连接数据库请求
一种mybaits-Plus mapper映射失败的容易被忽视的原因
大多数mapper映射失败的原因都是路径名称写没写对啊,文件放的位置对不对啊,参数对不对啊,但还有一种原因容易被人忽视。
那就是如果你自己写了 sqlSessionFactory的配置, 原本它是由Springboot 自动配置的所以他会自动去 你的配置文件里面找相关资源,但你自己写了sqlSessionFactory 的bean配置就需要像我这里一样自己手动配置一下 MapperLocations