首頁 > 軟體

基於SpringBoot整合SSMP的詳細教學

2022-08-09 18:00:20

基於SpringBoot實現SSMP整合

SpringBoot之所以好用,就是它能方便快捷的整合其他技術,這裡我們先介紹四種技術的整合:

  • 整合JUnit
  • 整合MyBatis
  • 整合MyBatis-Plus
  • 整合Druid

整合JUnit

​ SpringBoot技術的定位用於簡化開發,再具體點是簡化Spring程式的開發。所以在整合任意技術的時候,如果你想直觀感觸到簡化的效果,你必須先知道使用非SpringBoot技術時對應的整合是如何做的,然後再看基於SpringBoot的整合是如何做的,才能比對出來簡化在了哪裡。

​ 我們先來看一下不使用SpringBoot技術時,Spring整合JUnit的製作方式

//載入spring整合junit專用的類執行器
@RunWith(SpringJUnit4ClassRunner.class)
//指定對應的設定資訊
@ContextConfiguration(classes = SpringConfig.class)
public class AccountServiceTestCase {
    //注入你要測試的物件
    @Autowired
    private AccountService accountService;
    @Test
    public void testGetById(){
        //執行要測試的物件對應的方法
        System.out.println(accountService.findById(2));
    }
}

​其中核心程式碼是前兩個註解

第一個註解@RunWith是設定Spring專用的測試類執行器,簡單說就是Spring程式執行程式有自己的一套獨立的執行程式的方式,不能使用JUnit提供的類執行方式了,必須指定一下,但是格式是固定的,琢磨一下,每次都指定一樣的東西,這個東西寫起來沒有技術含量啊

第二個註解@ContextConfiguration是用來設定Spring核心組態檔或設定類的,簡單說就是載入Spring的環境你要告訴Spring具體的環境設定是在哪裡寫的,雖然每次載入的檔案都有可能不同,但是仔細想想,如果檔名是固定的,這個貌似也是一個固定格式。既然有可能是固定格式,那就有可能每次都寫一樣的東西,也是一個沒有技術含量的內容書寫

SpringBoot就抓住上述兩條沒有技術含量的內容書寫進行開發簡化,能走預設值的走預設值,能不寫的就不寫,具體格式如下:

@SpringBootTest
class Springboot04JunitApplicationTests {
    //注入你要測試的物件
    @Autowired
    private BookDao bookDao;
    @Test
    void contextLoads() {
        //執行要測試的物件對應的方法
        bookDao.save();
        System.out.println("two...");
    }
}

​ 看看這次簡化成什麼樣了,一個註解就搞定了,而且還沒有引數,再體會SpringBoot整合其他技術的優勢在哪裡,就兩個字——簡化使用一個註解@SpringBootTest替換了前面兩個註解。至於內部是怎麼回事?和之前一樣,只不過都走預設值

​ 這個時候有人就問了,你載入的設定類或者組態檔是哪一個?就是我們前面啟動程式使用的引導類。如果想手工指定引導類有兩種方式,第一種方式使用屬性的形式進行,在註解@SpringBootTest中新增classes屬性指定設定類:

@SpringBootTest(classes = 引導類的名字.class)
class Springboot04JunitApplicationTests {
    //注入你要測試的物件
    @Autowired
    private BookDao bookDao;
    @Test
    void contextLoads() {
        //執行要測試的物件對應的方法
        bookDao.save();
        System.out.println("two...");
    }
}

第二種方式迴歸原始設定方式,仍然使用@ContextConfiguration註解進行,效果是一樣的:

@SpringBootTest
@ContextConfiguration(classes = Springboot04JunitApplication.class)
class Springboot04JunitApplicationTests {
    //注入你要測試的物件
    @Autowired
    private BookDao bookDao;
    @Test
    void contextLoads() {
        //執行要測試的物件對應的方法
        bookDao.save();
        System.out.println("two...");
    }
}

溫馨提示
使用SpringBoot整合JUnit需要保障匯入test對應的starter,由於初始化專案時此項是預設匯入的,所以此處沒有提及

總結

  • 匯入測試對應的starter
  • 測試類使用@SpringBootTest修飾
  • 使用自動裝配的形式新增要測試的物件
  • 測試類如果存在於引導類所在包或子包中無需指定引導類
  • 測試類如果不存在於引導類所在的包或子包中需要通過classes屬性指定引導類

整合MyBatis

老規矩我們還是先寫一下原始整合方案:

匯入座標,MyBatis座標不能少,Spring整合MyBatis還有自己專用的座標,此外Spring進行資料庫操作的jdbc座標是必須的,剩下還有mysql驅動座標,本例中使用了Druid資料來源,這個倒是可以不要

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <!--1.匯入mybatis與spring整合的jar包-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>
    <!--匯入spring運算元據庫必選的包-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

Spring核心設定

@Configuration
@ComponentScan("com.nefu")
@PropertySource("jdbc.properties")
public class SpringConfig {
}

MyBatis要交給Spring接管的bean

//定義mybatis專用的設定類
@Configuration
public class MyBatisConfig {
//    定義建立SqlSessionFactory對應的bean
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
        //SqlSessionFactoryBean是由mybatis-spring包提供的,專用於整合用的物件
        SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();
        //設定資料來源替代原始設定中的environments的設定
        sfb.setDataSource(dataSource);
        //設定型別別名替代原始設定中的typeAliases的設定
        sfb.setTypeAliasesPackage("com.nefu.domain");
        return sfb;
    }
//    定義載入所有的對映設定
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.nefu.dao");
        return msc;
    }

}

資料來源對應的bean,此處使用Druid資料來源

@Configuration
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String userName;
    @Value("${jdbc.password}")
    private String password;

    @Bean("dataSource")
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}

資料庫連線資訊(properties格式)

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring_db?useSSL=false
jdbc.username=root
jdbc.password=*********

上述格式基本上是最簡格式了,要寫的東西還真不少。

這裡是最簡格式,所以我們沒有寫業務層,我們測試的時候直接通過dao的自動生成物件去運算元據庫

下面看看SpringBoot整合MyBaits格式:
步驟①:建立模組

步驟②:勾選要使用的技術,MyBatis,由於要運算元據庫,還要勾選對應資料庫

​ 或者手工匯入對應技術的starter,和對應資料庫的座標

<dependencies>
    <!--1.匯入對應的starter-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.0</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

步驟③:設定資料來源相關資訊,沒有這個資訊你連線哪個資料庫都不知道

#2.設定相關資訊
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db
    username: root
    password: ****************

​ 結束了,對,這就結束了,SpringBoot把設定中所有可能出現的通用設定都簡化了。下面寫一個MyBatis程式執行需要的Dao(或者Mapper)就可以執行了

實體類

public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;

	······
}

對映介面(Dao)

@Mapper
public interface BookDao {
    @Select("select * from tbl_book where id = #{id}")
    public Book getById(Integer id);
}

測試類

@SpringBootTest
class Springboot05MybatisApplicationTests {
    @Autowired
    private BookDao bookDao;
    @Test
    void contextLoads() {
        System.out.println(bookDao.getById(1));
    }
}

結果:

注意:當前使用的SpringBoot版本是2.5.4,對應的座標設定中Mysql驅動使用的是8x版本。使用SpringBoot2.4.3(不含)之前版本會出現一個小BUG,就是MySQL驅動升級到8以後要求強制設定時區,如果不設定會出問題。解決方案很簡單,驅動url上面新增上對應設定就行了

#2.設定相關資訊
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
    username: root
    password: ********

​ 這裡設定的UTC是全球標準時間,你也可以理解為是英國時間,中國處在東八區,需要在這個基礎上加上8小時,這樣才能和中國地區的時間對應的,也可以修改設定為Asia/Shanghai,同樣可以解決這個問題。

#2.設定相關資訊
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=Asia/Shanghai
    username: root
    password: *********

​ 如果不想每次都設定這個東西,也可以去修改mysql中的組態檔mysql.ini,在mysqld項中新增default-time-zone=+8:00也可以解決這個問題。其實方式方法很多,這裡就說這麼多吧。

​ 此外在執行程式時還會給出一個提示,說資料庫驅動過時的警告,根據提示修改設定即可,棄用com.mysql.jdbc.Driver,換用com.mysql.cj.jdbc.Driver。前面的例子中已經更換了驅動了,在此說明一下。

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.

總結

  • 整合操作需要勾選MyBatis技術,也就是匯入MyBatis對應的starter
  • 資料庫連線相關資訊轉換成設定
  • 資料庫SQL對映需要新增@Mapper被容器識別到
  • MySQL 8.X驅動強制要求設定時區
  • 修改url,新增serverTimezone設定
  • 修改MySQL資料庫設定
  • 驅動類過時,提醒更換為com.mysql.cj.jdbc.Driver

整合MyBatis-Plus

經過前面兩種技術的整合,我們發現第三方技術的整合無非就是兩步:

  • 匯入對應技術的starter座標
  • 根據對應技術的要求做設定

接下來在MyBatis的基礎上再升級一下,整合MyBaitsPlus(簡稱MP)

步驟①:匯入對應的starter

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3</version>
</dependency>

​ 關於這個座標,此處要說明一點,之前我們看的starter都是spring-boot-starter-???,也就是說都是下面的格式

Spring-boot-start-***

​ 而MyBatis與MyBatisPlus這兩個座標的名字書寫比較特殊,是第三方技術名稱在前,boot和starter在後。此處簡單提一下命名規範,後期原理篇會再詳細講解

starter所屬命名規則範例
官方提供spring-boot-starter-技術名稱spring-boot-starter-web
spring-boot-starter-test
第三方提供第三方技術名稱-spring-boot-startermybatis-spring-boot-starter
druid-spring-boot-starter
第三方提供第三方技術名稱-boot-starter(第三方技術名稱過長,簡化命名)mybatis-plus-boot-starter

溫馨提示

​ 有些小夥伴在建立專案時想通過勾選的形式找到這個名字,別翻了,沒有。截止目前,SpringBoot官網還未收錄此座標,而我們Idea建立模組時讀取的是SpringBoot官網的Spring Initializr,所以也沒有。如果換用阿里雲的url建立專案可以找到對應的座標。

步驟②:設定資料來源相關資訊

#2.設定相關資訊
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db
    username: root
    password: root

​ 沒了,就這麼多,剩下的就是寫MyBaitsPlus的程式了

對映介面(Dao)

@Mapper
public interface BookDao extends BaseMapper<Book> {
}

​ 核心在於Dao介面繼承了一個BaseMapper的介面,這個介面中幫助開發者預定了若干個常用的API介面,簡化了通用API介面的開發工作。

溫馨提示

目前資料庫的表名定義規則是tbl_模組名稱,為了能和實體類相對應,需要做一個設定,相關知識我前面mybatis-plus的文章中已經有詳細解釋,此處僅給出解決方案。設定application.yml檔案,新增如下設定即可,設定所有表名的通用字首名

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_		#設定所有表的通用字首名稱為tbl_

總結

  • 手工新增MyBatis-Plus對應的starter
  • 資料層介面使用BaseMapper簡化開發
  • 需要使用的第三方技術無法通過勾選確定時,需要手工新增座標 整合Druid

前面整合MyBatis和MyBatisPlus的時候,使用的資料來源物件都是SpringBoot預設的資料來源物件,下面我們手工控制一下,自己指定了一個資料來源物件,Druid。

​ 在沒有指定資料來源時,我們的設定如下:

#2.設定相關資訊
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=Asia/Shanghai
    username: root
    password: root

​ 此時雖然沒有指定資料來源,但是根據SpringBoot的德行,肯定幫我們選了一個它認為最好的資料來源物件,這就是HiKari。通過啟動紀錄檔可以檢視到對應的身影。

2021-11-29 09:39:15.202  INFO 12260 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-11-29 09:39:15.208  WARN 12260 --- [           main] com.zaxxer.hikari.util.DriverDataSource  : Registered driver with driverClassName=com.mysql.jdbc.Driver was not found, trying direct instantiation.
2021-11-29 09:39:15.551  INFO 12260 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.

​ 上述資訊中每一行都有HiKari的身影,如果需要更換資料來源,其實只需要兩步即可。

  • 匯入對應的技術座標
  • 設定使用指定的資料來源型別

下面就切換一下資料來源物件

步驟①:匯入對應的座標(注意,是座標,此處不是starter)

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
</dependencies>

步驟②:修改設定,在資料來源設定中有一個type屬性,專用於指定資料來源型別

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
    username: root
    password: *********
    type: com.alibaba.druid.pool.DruidDataSource

​ 這裡其實要提出一個問題的,目前的資料來源設定格式是一個通用格式,不管你換什麼資料來源都可以用這種形式進行設定。但是新的問題又來了,如果對資料來源進行個性化的設定,例如設定資料來源對應的連線數量,這個時候就有新的問題了。每個資料來源技術對應的設定名稱都一樣嗎?肯定不是啊,各個廠商不可能提前商量好都寫一樣的名字啊,怎麼辦?就要使用專用的設定格式了。這個時候上面這種通用格式就不能使用了,怎麼辦?還能怎麼辦?按照SpringBoot整合其他技術的通用規則來套啊,匯入對應的starter,進行相應的設定即可。

步驟①:匯入對應的starter

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.6</version>
    </dependency>
</dependencies>

步驟②:修改設定

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
      username: root
      password: *************

​ 注意觀察,設定項中,在datasource下面並不是直接設定url這些屬性的,而是先設定了一個druid節點,然後再設定的url這些東西。言外之意,url這個屬性是druid下面的屬性,那你能想到什麼?除了這4個常規設定外,還有druid專用的其他設定。通過提示功能可以開啟druid相關的設定查閱

與druid相關的設定超過200條以上,這就告訴你,如果想做druid相關的設定,使用這種格式就可以了,這裡就不展開描述了,太多了。

​ 這是我們做的第4個技術的整合方案,還是那兩句話:匯入對應starter,使用對應設定。沒了,SpringBoot整合其他技術就這麼簡單粗暴。

總結

  • 整合Druid需要匯入Druid對應的starter
  • 根據Druid提供的設定方式進行設定
  • 整合第三方技術通用方式
  • 匯入對應的starter
  • 根據提供的設定格式,設定非預設值對應的設定項

到此這篇關於SpringBoot如何整合SSMP的文章就介紹到這了,更多相關SpringBoot如何整合SSMP內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com