springboot引入mybatis遇到的坑

2022-06-12 15:00:40

  前邊分享了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多環境下如何進行動態設定