首先探究此問題并無什么實際意義,純屬是個人好奇使然,也順帶熟悉了一下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