springboot引入mybatis遇到的坑

良哥說技術發表於2022-06-12

  前邊分享了springboot專案的建立及springboot專案的預設配置檔案等,想溫習的小夥伴可移步至文章末尾閱讀,感謝。今天來分享下springboot引入mybatis框架的步驟,有小夥伴會說很簡單,引入依賴,加上配置就完事了,話是沒有錯的,但是你知道每一步都在做什麼嗎,本著知其然知其所以然的態度,一步一步實現mybatis框架的引入。會有很多意想不到的精彩,繼續下去吧。

一、引入mybatis的依賴

  在springboot中要使用mybatis的,必然要引入mybatis的依賴,使用過spring的小夥伴都知道要在spring專案中使用mybatis,除了要引入mybatis的依賴外,還要引入spring和mybatis結合的依賴,名字是mybatis-spring.XXX.jar。springboot摒棄了先引入mybaits,再引入mybatis-spring的不便,開發了下面的依賴

        <!--mybatis的依賴 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

  可以看到這是一個“starter”,要說明的是springboot開發了很多這樣的“starter”,提供springboot和其他中介軟體的整合。先看下“mybatis-spring-boot-starter”這樣一個starter都包含哪些依賴,

  在“mybatis-spring-boot-starter”的依賴中有“mybatis.3.5.7”和“mybatis-spring.2.0.6”,還有“spring-boot-starter-jdbc”和“mybaits-spring-boot-autoconfigure”兩個依賴,說明“mybatis-spring-boot-starter”不光引入了mybatis相關的依賴還有其他的。現在來嘗試下啟動程式看看是什麼情況,

可以看到程式自動退出了,很神奇什麼錯誤也沒打自動退出了,為了把異常列印出來在啟動類的程式碼中加入try catch,如下

package com.my.template;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * 啟動類
 * @date 2022/6/3 21:32
 */
@SpringBootApplication
public class BootServer {
    public static void main(String[] args) {
        try {
            SpringApplication.run(BootServer.class);
        }catch (Exception e){
           e.printStackTrace();
        }
    }
}

  再看下啟動日誌,

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: 
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: 
Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; 
nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: 
Failed to determine a suitable driver class
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:635)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)

  從日誌中大體可以看處在建立“dataSource”這個bean的時候報錯了,並且有這樣一個異常“org.springfraemwork.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException”,為什麼有這樣一個異常,而且沒有有引入有關“autoconfigure.jdbc”的包啊,還記得前邊在引入“mybatis-spring-boot-starter”的時候,其依賴了該包,所以拋該異常也不足為奇。另外上面還有“Failed to instantiate [com.zaxxer.hikari.HikariDataSource]”這樣一句,也是由於在“spring-boot-starter-jdbc”包中引入了相關依賴,

好了,上邊分析了,日誌中的異常情況。回到問題的開始點,為什麼會建立“dataSource”這樣一個bean,這是因為在springboot啟動的時候會預設建立一個名為“dataSource”的bean,放到spring的環境中。是如何建立的吶?是因為springboot有自動配置的功能,也就springboot啟動的時候會預設載入“spring-boot-autoconfigure”下的spring.factories檔案中的類,

在“spring.factories”檔案中有這樣一個類“org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration”,該類是DataSouce的自動配置類,

另外,重要的一點是,springboot在不配置資料來源的時候預設使用的是“HikariDataSource”,這也是為什麼在依賴中會出現“com.zaxxer.HikarCP”依賴的原因,

要建立HikariDataSource,比然要建立資料庫連線,那麼就需要資料庫的驅動,由於沒有在application.properties檔案中配置,那麼程式碼肯定會走到下面的地方,

也就會出現啟動過程中下面的錯誤,

分析到這裡,問題就很明顯了,springboot在預設情況下要建立HikariDataSource的資料來源,最終其實是要建立資料庫連線,建立資料庫連線就需要資料庫啟動程式,這裡沒有資料庫驅動所以報錯了

  我這裡要連線mysql資料庫,這裡把mysql的資料庫驅動依賴再加上,

<!--mysql的驅動程式-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>

重要的一點在application.properites中配置,

server.port=9099
#資料庫驅動
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#使用者名稱
spring.datasource.username=root
spring.datasource.password=root
#連線地址
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test

注意,在配置的時候不要配置”spring.datasource.hikari“開頭的屬性,筆者開始的時候,想著這裡使用的是”hikariDataSource“,那麼我配置”spring.datasouce.hikari“字首的屬性即可,結果老是不對,這裡一定要配置的是”spring.datasource“開頭的屬性。

配置以後,再啟動服務,如下

可以看到這裡已經正常啟動了,俗話說沒有報錯就是最好的,並且在上圖也提示,”No MyBatis mapper war found in [com.my.template] package“,也就是說springboot預設會掃描mapper檔案。

二、HikariDataSource是什麼

  上面提到springboot預設的資料來源是HikariDataSource,那麼HikariDataSource是什麼?HikariDataSource是一個資料庫連線池,其github地址為:https://github.com/brettwooldridge/HikariCP,和平時使用的c3p0、dbcp2、druid是一樣的,前面說到HikariDataSource是sprinboot預設的資料庫連線池,只要引入了”spring-boot-starter-jdbc“,那麼HikariDataSource會預設引入,而且在application.properties中無需指定資料來源的型別,

spring.datasource.type=com.zaxxer.hikari.HikariDataSource

如果想使用其他的也可以,需要引入相應的依賴,然後在application.properties中進行配置,以Druid為例,

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

  後面,會對常用的資料庫連線池做一個彙總,敬請關注。

三、總結

  本文主要分享了在springboot中使用mybatis的一些問題,

  1、springboot預設的資料來源為HikariDataSource,可以通過spring.datasource.type來修改;

  2、配置HikariDataSource的時候,注意配置”spring.datasource“字首的屬性;

  3、springboot中使用mybatis,直接引入”mybatis-spring-boot-starter“更方便,不過要注意版本;

  4、除了引入mybatis的相關依賴,不要忘了引入相關的資料庫驅動jar;

 

最後,遺留一個小問題,mybatis-spring-boot-starter是什麼,你想過嗎,下期更精彩!

推薦閱讀

5分鐘快速搭建一個springboot的專案

springboot竟然有5種預設的載入路徑,你未必都知道

springboot如何使用自定義配置檔案

springboot多環境下如何進行動態配置

springboot引入mybatis遇到的坑

相關文章