Spring boot 2.0整合mybatis和druid數據源,基于starter方式

要點簡介

  • 快速搭建基于mybatis和druid的spring boot 2.0工程
  • 聊聊druid數據源和2.0默認的HikariCP數據源
  • 聊聊starter 以及 不用starter方式配置的異同

一、起因

最近了解到spring boot2.0有很多新特性,比如支持基于響應式編程的spring webflux,于是準備在2.0上造一些輪子。但是每次搭建spring boot框架的時候,都會遇到數據源相關配置問題,以前也就是百度一下,也沒有仔細的思考,所以這次也就特意整理了一下,理一理思路。

1.1 數據源的選擇

  • 《為什么HikariCP被號稱為性能最好的Java數據庫連接池,如何配置使用》

  • spring boot 2.0將默認的數據源更換為HikariCP,HiKariCP是數據庫連接池的一個后起之秀,號稱性能最好,可以完美地PK掉其他連接池,是一個高性能的JDBC連接池,基于BoneCP做了不少的改進和優化。

  • 而druid具有豐富的sql攔截與監控統計功能,想知道你的系統都操作了哪些sql、執行時間怎么樣,druid能告訴你細節

所以很多時候,為了開發方便,了解自己系統的短板,國內(包括我自己)很多時候還是選擇的druid作為自己的數據源。

1.2 關于spring boot的starter

本節參考了博客《Spring Boot Starters》
https://www.nosuchfield.com/2017/10/15/Spring-Boot-Starters/

starter是 spring boot 提出的一個概念,在之前的工作中,我就有注意到應用了starter的項目在“某些”配置上可能就會簡略不少,比如不用寫java配置類了,也不用寫xml配置文件了等等,可能很多時候我們都沒有仔細思考過spring boot 提出這個概念的原因。StackOverflow有人描述了其中的思想。

Starter POMs are a set of convenient dependency descriptors that you can include in your application. You get a one-stop-shop for all the Spring and related technology that you need, without having to hunt through sample code and copy paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, just include the spring-boot-starter-data-jpa dependency in your project, and you are good to go.

1.2.1 未使用starter之前的做法

如果要集成mybatis和druid這兩個工具,我們之前要

  • 引入druid依賴
  • 引入mybatis、mybatis-spring依賴
  • 使用java配置方式一次創建DataSource數據源、SqlSessionFactoryBean以及事務管理的類
//代碼段 1.1 數據源配置類、mybatis配置類
@Configuration
public class DruidConfig {
    @Autowired
    private Environment env;
    @Primary
    @Bean
    @ConfigurationProperties("spring.datasource.druid")
    public DataSource dataSource(){
        return DruidDataSourceBuilder.create().build();
    }
    @Bean
    @ConfigurationProperties(prefix = "mybatis")
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource());
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapper-locations")));
        return sqlSessionFactoryBean;
    }

    /**
     * 注入 DataSourceTransactionManager 用于事務管理
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

}
<!--代碼段1.2 這三個絕對不會少的POM依賴-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.0</version>
</dependency>
 <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.2</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>

1.2.2 Stater的原理

類似這樣的配置層出不窮,而且不同的人寫出的也不完全一樣,有的非關鍵配置在部分博客里也添油加醋進去,通用性很差。所以,在這樣的情況下,官方或者民間有些人就寫了各種starter來簡化我們的配置。

starter的理念:
starter會把所有用到的依賴都給包含進來,避免了開發者自己去引入依賴所帶來的麻煩。需要注意的是不同的starter是為了解決不同的依賴,所以它們內部的實現可能會有很大的差異,例如jpa的starter和Redis的starter可能實現就不一樣,這是因為starter的本質在于synthesize,這是一層在邏輯層面的抽象,也許這種理念有點類似于Docker,因為它們都是在做一個“包裝”的操作,如果你知道Docker是為了解決什么問題的,也許你可以用Docker和starter做一個類比。

starter的實現:
雖然不同的starter實現起來各有差異,但是他們基本上都會使用到兩個相同的內容:ConfigurationProperties和AutoConfiguration。因為Spring Boot堅信“約定大于配置”這一理念,所以我們使用ConfigurationProperties來保存我們的配置,并且這些配置都可以有一個默認值,即在我們沒有主動覆寫原始配置的情況下,默認值就會生效,這在很多情況下是非常有用的。除此之外,starter的ConfigurationProperties還使得所有的配置屬性被聚集到一個文件中(一般在resources目錄下的application.properties),這樣我們就告別了Spring項目中XML地獄。

spring-boot-stater原理

二、基于starter方式搭建

有了上面的認識,基于starter方式整合mybatis和druid就方便多了。一方面到目前為止,druid和mybatis官方都給出了starter的maven包以及配置范例。我們只需要在項目里依賴他們就可以使用了。下面依次是項目結構、pom文件以及boot的配置文件。


項目結構
<!--代碼段1.3 pom文件-->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
    </parent>
    <groupId>com</groupId>
    <artifactId>iview1</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork><!-- 如果沒有該項配置,肯呢個devtools不會起作用,即應用不會restart -->
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
<!--代碼段1.4 application.properites-->

#datasource
spring.datasource.druid.url=jdbc:mysql://localhost:3306/iview?characterEncoding=utf8&allowMultiQueries=true
spring.datasource.druid.username=root
spring.datasource.druid.password=root
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.druid.type = com.alibaba.druid.pool.DruidDataSource
#mapper.xml文件所在地址-位于resource下面的mapper文件夾下
mybatis.mapper-locations=classpath:mapper/*/*.xml
#log日志級別
logging.level.com=debug
<!--代碼段1.5 UserMapper-->
@Mapper
@Repository
public interface UserMapper {

    User getUserById(@Param("id")Integer id);
}

<!--代碼段1.6 UserMapper.xml-->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 指定工作空間,要與接口名相同,源代碼沒有去看,猜測應該是通過"這里的namespace.下邊方法的id"來定位方法的 -->
<mapper namespace="com.system.dao.UserMapper">
    <select id="getUserById"   resultType="com.system.model.User">
        select * from user where id = #{id}
    </select>
</mapper>

最后就是不要忘了,在啟動類文件中,標明要掃描的mapper的位置MapperScan注解

<!--代碼段1.7 啟動文件-->
@SpringBootApplication
@ComponentScan(basePackages = "com")
@MapperScan("com.*.dao")
public class IviewApplication {

    public static void main(String[] args){
        SpringApplication.run(IviewApplication.class);
    }

}

這樣配置就算完了,沒有關于數據源的任何配置。啟動的時候你可以看到日志提示

2018-07-23 22:04:14.686  INFO 7188 --- [           main] c.a.d.s.b.a.DruidDataSourceAutoConfigure : Init DruidDataSource
2018-07-23 22:04:14.842  INFO 7188 --- [           main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2018-07-23 22:04:15.398  INFO 7188 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin/getById]}" onto public com.system.model.User com.system.controller.LoginController.getById(java.lang.Integer)
2018-07-23 22:04:15.399  INFO 7188 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin/dologin],methods=[POST]}" onto public java.lang.String com.system.controller.LoginController.login(com.system.model.User)

訪問controller的時候也有sql日志打出

2018-07-23 22:05:45.146 DEBUG 7188 --- [nio-8090-exec-1] com.system.dao.UserMapper.getUserById    : ==>  Preparing: select * from user where id = ? 
2018-07-23 22:05:45.164 DEBUG 7188 --- [nio-8090-exec-1] com.system.dao.UserMapper.getUserById    : ==> Parameters: 1(Integer)
2018-07-23 22:05:45.201 DEBUG 7188 --- [nio-8090-exec-1] com.system.dao.UserMapper.getUserById    : <==      Total: 1

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容