1. 程式人生 > >MyBatis初級實戰之三:springboot整合druid

MyBatis初級實戰之三:springboot整合druid

OpenWrite版: ### 歡迎訪問我的GitHub [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) 內容:所有原創文章分類彙總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等; 本文是《MyBatis初級實戰》系列的第三篇,我們將實戰springboot、mybatis、druid的整合,並驗證; ### 關於druid 1. Druid是資料庫連線池,並且能夠提供強大的監控和擴充套件功能; 2. 官方GitHub地址:https://github.com/alibaba/druid 3. 本次整合使用了durid官方的starter,名為druid-spring-boot-starter,版本1.1.17,對應druid版本是1.1.17 ### 本篇概覽 本文由以下內容組成: 1. 新建springboot工程,裡面有詳細的整合druid的操作; 2. 編寫和執行單元測試程式碼,並規避一個由整合druid帶來的問題; 3. 啟動springboot應用,通過swagger驗證基本功能正常; 4. 通過斷點,確認使用了druid連線池; 5. 體驗druid提供的監控頁面; ### 原始碼下載 1. 如果您不想編碼,可以在GitHub下載所有原始碼,地址和連結資訊如下表所示(https://github.com/zq2599/blog_demos): | 名稱 | 連結 | 備註| | :-------- | :----| :----| | 專案主頁| https://github.com/zq2599/blog_demos | 該專案在GitHub上的主頁 | | git倉庫地址(https)| https://github.com/zq2599/blog_demos.git | 該專案原始碼的倉庫地址,https協議 | | git倉庫地址(ssh)| [email protected]:zq2599/blog_demos.git | 該專案原始碼的倉庫地址,ssh協議 | 2. 這個git專案中有多個資料夾,本章的應用在mybatis資料夾下,如下圖紅框所示: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119074957252-1685426587.png) ### springboot+mybatis+druid+swagger整合步驟小結 將整個整合所需步驟列舉如下,避免遺漏: 1. 建立springboot工程; 2. pom.xml中加入mybaits、druid、swagger依賴; 3. 配置mybatis-config.xml; 4. 配置application.yml,裡面有資料來源、mybatis、druid; 5. springboot啟動類,指定MapperScan; 6. swagger配置類; 7. druid配置類; 8. 資料庫實體類; 9. mybatis的mapper配置檔案; 10. mybatis的mapper類; 11. 業務程式碼; - 後續按照上述清單進行開發即可; ### 開發 1. 本文的實戰使用的資料庫和表結構與[《MyBatis初級實戰之一:Spring Boot整合》](https://blog.csdn.net/boling_cavalry/article/details/107805840)一模一樣; 2. 前文[《MyBatis初級實戰之一:Spring Boot整合》](https://blog.csdn.net/boling_cavalry/article/details/107805840)建立了父工程mybatis,本文繼續在此工程中新增子工程,名為druidonesource,整個子工程檔案結構如下: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119074957675-1467233884.png) 3. 在父工程中新增druid的版本管理: ```xml ``` 4. 新工程druidonesource的pom.xml內容如下: ```xml ``` 5. 新建mybatis-config.xml: ```xml ``` 6. 配置application.yml,請重點關注druid的配置,還請注意stat-view-servlet,這裡是druid監控頁面的登入配置: ```yml server: port: 8080 spring: #1.JDBC資料來源 datasource: username: root password: 123456 url: jdbc:mysql://192.168.50.43:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver #2.連線池配置 druid: #初始化連線池的連線數量 大小,最小,最大 initial-size: 5 min-idle: 5 max-active: 20 #配置獲取連線等待超時的時間 max-wait: 60000 #配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 time-between-eviction-runs-millis: 60000 # 配置一個連線在池中最小生存的時間,單位是毫秒 min-evictable-idle-time-millis: 30000 # 配置一個連線在池中最大生存的時間,單位是毫秒 max-evictable-idle-time-millis: 300000 validation-query: SELECT 1 FROM user test-while-idle: true test-on-borrow: true test-on-return: false # 是否快取preparedStatement,也就是PSCache 官方建議MySQL下建議關閉 個人建議如果想用SQL防火牆 建議開啟 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 # 配置監控統計攔截的filters,去掉後監控介面sql無法統計,'wall'用於防火牆 filters: stat,wall,slf4j filter: stat: merge-sql: true slow-sql-millis: 5000 #3.基礎監控配置 web-stat-filter: enabled: true url-pattern: /* #設定不統計哪些URL exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" session-stat-enable: true session-stat-max-count: 100 stat-view-servlet: enabled: true url-pattern: /druid/* reset-enable: true #設定監控頁面的登入名和密碼 login-username: admin login-password: admin allow: 127.0.0.1 #deny: 192.168.1.100 # mybatis配置 mybatis: # 配置檔案所在位置 config-location: classpath:mybatis-config.xml # 對映檔案所在位置 mapper-locations: classpath:mappers/*Mapper.xml # 日誌配置 logging: level: root: INFO com: bolingcavalry: druidonesource: mapper: debug ``` 7. 建立啟動類,要帶上MapperScan註解: ```java package com.bolingcavalry.druidonesource; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.bolingcavalry.druidonesource.mapper") public class DuridOneSourceApplication { public static void main(String[] args) { SpringApplication.run(DuridOneSourceApplication.class, args); } } ``` 8. 建立swagger配置類: ```java package com.bolingcavalry.druidonesource; import springfox.documentation.service.Contact; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Tag; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; /** * @Description: swagger配置類 * @author: willzhao E-mail: [email protected] * @date: 2020/8/11 7:54 */ @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .tags(new Tag("UserController", "使用者服務"), new Tag("LogController", "日誌服務")) .select() // 當前包路徑 .apis(RequestHandlerSelectors.basePackage("com.bolingcavalry.druidonesource.controller")) .paths(PathSelectors.any()) .build(); } //構建 api文件的詳細資訊函式,注意這裡的註解引用的是哪個 private ApiInfo apiInfo() { return new ApiInfoBuilder() //頁面標題 .title("MyBatis CURD操作") //建立人 .contact(new Contact("程式設計師欣宸", "https://github.com/zq2599/blog_demos", "[email protected]")) //版本號 .version("1.0") //描述 .description("API 描述") .build(); } } ``` 9. 建立druid配置類,如下,可見是通過使用application.yml中配置的引數對DruidDataSource進行配置: ```java package com.bolingcavalry.druidonesource; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Description: druid配置類 * @author: willzhao E-mail: [email protected] * @date: 2020/8/18 08:12 */ @Configuration public class DruidConfig { private static final Logger logger = LoggerFactory.getLogger(DruidConfig.class); @Value("${spring.datasource.url}") private String dbUrl; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.driver-class-name}") private String driverClassName; @Value("${spring.datasource.druid.initial-size}") private int initialSize; @Value("${spring.datasource.druid.max-active}") private int maxActive; @Value("${spring.datasource.druid.min-idle}") private int minIdle; @Value("${spring.datasource.druid.max-wait}") private int maxWait; @Value("${spring.datasource.druid.pool-prepared-statements}") private boolean poolPreparedStatements; @Value("${spring.datasource.druid.max-pool-prepared-statement-per-connection-size}") private int maxPoolPreparedStatementPerConnectionSize; @Value("${spring.datasource.druid.time-between-eviction-runs-millis}") private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.druid.min-evictable-idle-time-millis}") private int minEvictableIdleTimeMillis; @Value("${spring.datasource.druid.max-evictable-idle-time-millis}") private int maxEvictableIdleTimeMillis; @Value("${spring.datasource.druid.validation-query}") private String validationQuery; @Value("${spring.datasource.druid.test-while-idle}") private boolean testWhileIdle; @Value("${spring.datasource.druid.test-on-borrow}") private boolean testOnBorrow; @Value("${spring.datasource.druid.test-on-return}") private boolean testOnReturn; @Value("${spring.datasource.druid.filters}") private String filters; @Value("{spring.datasource.druid.connection-properties}") private String connectionProperties; /** * Druid 連線池配置 */ @Bean public DruidDataSource dataSource() { DruidDataSource datasource = new DruidDataSource(); datasource.setUrl(dbUrl); datasource.setUsername(username); datasource.setPassword(password); datasource.setDriverClassName(driverClassName); datasource.setInitialSize(initialSize); datasource.setMinIdle(minIdle); datasource.setMaxActive(maxActive); datasource.setMaxWait(maxWait); datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setMaxEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setValidationQuery(validationQuery); datasource.setTestWhileIdle(testWhileIdle); datasource.setTestOnBorrow(testOnBorrow); datasource.setTestOnReturn(testOnReturn); datasource.setPoolPreparedStatements(poolPreparedStatements); datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); try { datasource.setFilters(filters); } catch (Exception e) { logger.error("druid configuration initialization filter", e); } datasource.setConnectionProperties(connectionProperties); return datasource; } } ``` 10. 接下來的資料實體類、mapper配置、mapper介面類、業務程式碼等,除了package不一樣,其他的與上一章[《MyBatis初級實戰之二:增刪改查》](https://xinchen.blog.csdn.net/article/details/107971293)一模一樣,請參考github原始碼或者上一篇文章來編寫,這裡就不佔篇幅了; ### 單元測試(特別注意) 單元測試時有個問題要特別注意,就是關閉監控功能,否則會導致單元測試失敗; 1. 新建名為application-test.yml的檔案,內容和application.yml一樣,僅下圖紅框中的值不同: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119074958028-610952898.png) 2. 單元測試類UserControllerTest的內容與上一章[《MyBatis初級實戰之二:增刪改查》](https://xinchen.blog.csdn.net/article/details/107971293)一樣,僅下圖紅框位置是新增的,用於指定使用application-test.yml配置檔案: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119074958412-425535942.png) ### 驗證,單元測試 如下圖紅框的操作,即可完成單元測試: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075000204-329086645.png) ### 驗證,swagger 1. 執行DuridOneSourceApplication類啟動應用; 2. 瀏覽器開啟:http://localhost:8080/swagger-ui.htm,操作如下: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075000645-804550934.png) 3. 得到響應操作成功,並返回了主鍵ID: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075000852-1663964850.png) 4. 其他介面也可以通過類似操作在swagger頁面上完成; ### 確認使用了druid連線池 1. 上面的操作證明咱們的spring boot應用可以操作資料庫,但沒辦法證明用的是druid資料來源(沒準用的還是spring boot的預設datasource),因此需要有種更直接的方式來檢查資料來源詳情,因此採用了打斷點的手段,檢視資料來源例項; 2. 給UserMapper介面insertWithFields方法的打上斷點,如下圖紅框: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075001026-107206399.png) 3. 如下圖,在DuridOneSourceApplication類上點選滑鼠右鍵,選擇紅框中的選項,即可以debug的方式啟動應用: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075001746-930129139.png) 4. 啟動日誌如下圖紅框,可見debug模式下啟動速度很慢,請耐心等待: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075002290-267763730.png) 5. 再次呼叫方法就會進入斷點位置,這時候可以展開UserMapper對應例項的變數,如下圖紅框所示,可以確定使用了druid的連線池: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075002802-1107287721.png) 6. 上一篇文章中的工程curd沒有使用druid,咱們也打上斷點看看資料來源啥樣的,如下圖所示,是個HikariDataSource例項: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075003303-135054555.png) ### 體驗druid提供的監控頁面 1. 執行DuridOneSourceApplication類啟動應用; 2. 瀏覽器訪問:http://localhost:8080/druid ,如下圖,賬號密碼都是admin(在application.yml中配置的): ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075003546-1167647490.png) 3. 在swagger上呼叫幾次介面對資料庫進行操作,之後回到druid頁面,如下圖,可見已經監控到了具體的資料庫操作: ![在這裡插入圖片描述](https://img2020.cnblogs.com/other/485422/202101/485422-20210119075004038-1175264827.png) - 至此,springboot+mybatis+druid整合的開發和驗證就完成了,希望本文能給您一些參考; ### 你不孤單,欣宸原創一路相伴 1. [Java系列](https://xinchen.blog.csdn.net/article/details/105068742) 2. [Spring系列](https://xinchen.blog.csdn.net/article/details/105086498) 3. [Docker系列](https://xinchen.blog.csdn.net/article/details/105086732) 4. [kubernetes系列](https://xinchen.blog.csdn.net/article/details/105086794) 5. [資料庫+中介軟體系列](https://xinchen.blog.csdn.net/article/details/105086850) 6. [DevOps系列](https://xinchen.blog.csdn.net/article/details/105086920) ### 歡迎關注公眾號:程式設計師欣宸 > 微信搜尋「程式設計師欣宸」,我是欣宸,期待與您一同暢遊Java世界... [https://github.com/zq2599/blog_demos](https://github.com/zq2599/blo