SpringBoot整合MyBatisPlus配置動態數據源

SpringBoot整合MyBatisPlus配置動態數據源

推文:2018開源中國最受歡迎的中國軟件MyBatis-Plushtml

MybatisPlus特性
  • 無侵入:只作加強不作改變,引入它不會對現有工程產生影響,如絲般順滑
  • 損耗小:啓動即會自動注入基本 CURD,性能基本無損耗,直接面向對象操做
  • 強大的 CRUD 操做:內置通用 Mapper、通用 Service,僅僅經過少許配置便可實現單表大部分 CRUD 操做,更有強大的條件構造器,知足各種使用需求
  • 支持 Lambda 形式調用:經過 Lambda 表達式,方便的編寫各種查詢條件,無需再擔憂字段寫錯
  • 支持多種數據庫:支持 MySQL、MariaDB、Oracle、DB二、H二、HSQL、SQLite、Postgre、SQLServer200五、SQLServer 等多種數據庫
  • 支持主鍵自動生成:支持多達 4 種主鍵策略(內含分佈式惟一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題
  • 支持 XML 熱加載:Mapper 對應的 XML 支持熱加載,對於簡單的 CRUD 操做,甚至能夠無 XML 啓動
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式調用,實體類只需繼承 Model 類便可進行強大的 CRUD 操做
  • 支持自定義全局通用操做:支持全局通用方法注入( Write once, use anywhere )
  • 支持關鍵詞自動轉義:支持數據庫關鍵詞(order、key......)自動轉義,還可自定義關鍵詞
  • 內置代碼生成器:採用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用
  • 內置分頁插件:基於 MyBatis 物理分頁,開發者無需關心具體操做,配置好插件以後,寫分頁等同於普通 List 查詢
  • 內置性能分析插件:可輸出 Sql 語句以及其執行時間,建議開發測試時啓用該功能,能快速揪出慢查詢
  • 內置全局攔截插件:提供全表 delete 、 update 操做智能分析阻斷,也可自定義攔截規則,預防誤操做
  • 內置 Sql 注入剝離器:支持 Sql 注入剝離,有效預防 Sql 注入攻擊
快速開始

初始化測試數據表:java

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主鍵ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年齡',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '郵箱',
    PRIMARY KEY (id)
);
DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

父工程依賴mysql

該工程用於依賴管理,pom以下:git

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
        <mybatis-plus-version>3.1.1</mybatis-plus-version>
        <mysql-driver-version>5.1.47</mysql-driver-version>
        <druid-version>1.1.10</druid-version>
 </properties>

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.5.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

建立MyBaitsPlus工程github

依賴以下:web

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- mybatis plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus-version}</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-driver-version}</version>
        </dependency>

        <!-- druid數據鏈接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid-version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
 </dependencies>
properties配置

在這裏配置數據庫鏈接,以及數據鏈接池與mybatisplus的配置等spring

server.port=8080

spring.application.name=mybatis

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

spring.datasource.druid.initial-size=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.maxActive=20
spring.datasource.druid.maxWait=60000
spring.datasource.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.minEvictableIdleTimeMillis=300000
spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.druid.testWhileIdle=true
spring.datasource.druid.testOnBorrow=false
spring.datasource.druid.testOnReturn=false
spring.datasource.druid.poolPreparedStatements=true
spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.druid.filters=stat,slf4j
spring.datasource.druid.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
spring.datasource.druid.web-stat-filter.enabled=true
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
spring.datasource.druid.stat-view-servlet.deny=192.168.1.73
spring.datasource.druid.stat-view-servlet.reset-enable=false
#Druid 管理帳號
spring.datasource.druid.stat-view-servlet.login-username=admin
#Druid 管理密碼
spring.datasource.druid.stat-view-servlet.login-password=123456
#com.simple.spring.boot.mapper 該包打印DEBUG級別日誌
logging.level.com.simple.spring.boot.mapper=debug

#mybatis plus mapper文件路徑
mybatis-plus.mapperLocations=classpath:/mybatis/mapper/*.xml
#mybaits plus 實體類路徑
mybatis-plus.typeAliasesPackage=com.simple.spring.**.entities
mybatis-plus.typeEnumsPackage=
#數據庫相關配置
#主鍵類型  AUTO:"數據庫ID自增", INPUT:"用戶輸入ID",ID_WORKER:"全局惟一ID (數字類型惟一ID)", UUID:"全局惟一ID UUID";
mybatis-plus.global-config.db-config.id-type=UUID
#字段策略 IGNORED:"忽略判斷",NOT_NULL:"非 NULL 判斷"),NOT_EMPTY:"非空判斷"
mybatis-plus.global-config.db-config.field-strategy=not_empty
#駝峯下劃線轉換
mybatis-plus.global-config.db-config.column-underline=true
#數據庫大寫下劃線轉換
#capital-mode: true
#邏輯刪除配置
mybatis-plus.global-config.db-config.logic-delete-value=0
mybatis-plus.global-config.db-config.logic-not-delete-value= 1
#mybatis-plus.global-config.db-config.db-type= sqlserver
#刷新mapper 調試神器
mybatis-plus.global-config.refresh=true
# 原生配置
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false
mybatis-plus.configuration.call-setters-on-nulls =true
常規增刪改查實現

建立實體類:sql

**
 * 實體類
 * @author: SimpleWu
 * @date: 2019/5/25
 */
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

lombok插件省去getset方法。數據庫

建立UserMapper接口,而且實現BaseMapper<User>這裏咱們指定實體類爲user可直接使用接口中的方法。

  • 查詢全部數據

    public List<User> getList(){
            return userMapper.selectList(null);
    }
  • 查詢數據帶查詢條件

    public List<User> getListQuery(){
            User user = new User();
            user.setName("SimpleWu");
            Wrapper<User> wrapper = new QueryWrapper<>(user);
            return userMapper.selectList(wrapper);
    }
  • 查詢帶分頁

    public IPage<User> page(){
            int currentPage = 1 ; //當前頁
            int pageSize = 2 ;//每頁大小
            IPage<User> page = new Page(currentPage,pageSize);
            page = userMapper.selectPage(page,null);
            return page;
     }
  • 根據實體類新增數據

    @Transactional//本地事務開啓
    public int insert(){
            User user = new User();
            user.setId(6l);
            user.setName("SimpleWu");
            user.setAge(100);
            user.setEmail("SimpleWu@gmail.com");
            return userMapper.insert(user);
     }
  • 根據主鍵刪除數據

    @Transactional//本地事務開啓
     public int deleteById(){
            int userId = 6;
            return userMapper.deleteById(userId);
    }
  • 根據ID更新數據

    @Transactional//本地事務開啓
     public int updateById(){
            User user = new User();
            user.setId(5l);
            user.setName("update");
            user.setAge(100);
            user.setEmail("update@email.com");
           return userMapper.updateById(user);
    }
  • 條件構造器

    • UpdateWrapper 用於增刪改構造條件
    • QueryWrapper 用於查詢構造條件
    Transactional//本地事務開啓
        public int updateWrapperUser(){
            User user = new User();
            user.setId(5l);
            user.setName("update");
            user.setAge(100);
            user.setEmail("update@email.com");
    
            User updateWrapperUser = new User();
            updateWrapperUser.setId(1l);
    
            /**
             * 修改 UpdateWrapper
             * 查詢 QueryWrapper
             */
            Wrapper<User> wrapper = new UpdateWrapper<>(updateWrapperUser);
            return userMapper.update(user,wrapper);
     }
  • Mapper接口綁定Mapper文件

    • properites中配置既可

      #掃描mybatis/mapper下面的全部xml
      mybatis-plus.mapperLocations=classpath:/mybatis/mapper/*.xml
  • UserMapper接口測試

public interface UserMapper extends BaseMapper<User> {

    Map<String,Object> queryUser(@Param("USER_ID") String userId);
}

UserMapper.xml,以下:

<select id="queryUser" resultType="java.util.HashMap" parameterType="java.lang.String">
        SELECT
          ID,
          NAME
        FROM
          USER
        WHERE ID = #{USER_ID}
</select>

執行SQL:

public Map<String,Object> myMapper(){
        return userMapper.queryUser("2");
}

在SpringBoot中使用MybatisPlus分頁須要注入Bean,而且在啓動類上使用@MapperScan("com.simple.spring.boot.mapper")掃描mapper文件路徑以下:

@SpringBootApplication
@MapperScan("com.simple.spring.boot.mapper")
public class MybatisPlusApplication {

    /**
     * 分頁插件註冊
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

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

}

使用MyBatisPlus能夠爲咱們減小不少不少的代碼,不過須要編寫實體類,有失必有得。

配置動態數據源

dynamic-datasource-spring-boot-starter 是一個基於springboot的快速集成多數據源的啓動器。

優點

網上關於動態數據源的切換的文檔有不少,核心只有兩種。

  1. 構建多套環境,優點是方便控制也容易集成一些簡單的分佈式事務,缺點是非動態同時代碼量較多,配置難度大。
  2. 基於spring提供原生的 AbstractRoutingDataSource ,參考一些文檔本身實現切換。

若是你的數據源較少,場景不復雜,選擇以上任意一種均可以。若是你須要更多特性,請嘗試本動態數據源。

  1. 數據源分組,適用於多種場景 純粹多庫 讀寫分離 一主多從 混合模式。
  2. 簡單集成Druid數據源監控多數據源,簡單集成Mybatis-Plus簡化單表,簡單集成P6sy格式化sql,簡單集成Jndi數據源。
  3. 簡化Druid和HikariCp配置,提供全局參數配置。
  4. 提供自定義數據源來源(默認使用yml或properties配置)。
  5. 項目啓動後能動態增減數據源。
  6. 使用spel動態參數解析數據源,如從session,header和參數中獲取數據源。(多租戶架構神器)
  7. 多層數據源嵌套切換。(一個業務ServiceA調用ServiceB,ServiceB調用ServiceC,每一個Service都是不一樣的數據源)
  8. 使用正則匹配或spel表達式來切換數據源(實驗性功能)。

劣勢

不能使用多數據源事務(同一個數據源下能使用事務),網上其餘方案也都不能提供。

若是你須要使用到分佈式事務,那麼你的架構應該到了微服務化的時候了。

若是呼聲強烈,項目達到800 star,做者考慮集成分佈式事務。

PS: 若是您只是幾個數據庫可是有強烈的需求分佈式事務,建議仍是使用傳統方式本身構建多套環境集成atomic這類,網上百度不少。

約定

  1. 本框架只作 切換數據源 這件核心的事情,並不限制你的具體操做,切換了數據源能夠作任何CRUD。
  2. 配置文件全部如下劃線 _ 分割的數據源 首部 即爲組的名稱,相同組名稱的數據源會放在一個組下。
  3. 切換數據源便可是組名,也但是具體數據源名稱,切換時默認採用負載均衡機制切換。
  4. 默認的數據源名稱爲 master ,你能夠經過spring.datasource.dynamic.primary修改。
  5. 方法上的註解優先於類上註解。

建議

強烈建議在 主從模式 下遵循廣泛的規則,以便他人能更輕易理解你的代碼。

主數據庫 建議 只執行 INSERT UPDATE DELETE 操做。

從數據庫 建議 只執行 SELECT 操做。

快速開始

加入依賴:

<!-- 動態數據源 -->
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>2.5.4</version>
</dependency>

註釋掉原來的數據庫配置,加入:

#設置默認的數據源或者數據源組,默認值即爲master
spring.datasource.dynamic.primary=master
#主庫配置
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=root
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&characterEncoding=utf8
#從庫配置
spring.datasource.dynamic.datasource.slave_1.username=root
spring.datasource.dynamic.datasource.slave_1.password=root
spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://localhost:3307/mybatis?useSSL=false&characterEncoding=utf8

使用 @DS 切換數據源。

@DS("master")
    public List<User> getListQuery(){
        User user = new User();
        user.setName("SimpleWu");
        Wrapper<User> wrapper = new QueryWrapper<>(user);
        return userMapper.selectList(wrapper);
    }

    @DS("slave_1")
    public IPage<User> page(){
        int currentPage = 1 ; //當前頁
        int pageSize = 2 ;//每頁大小
        IPage<User> page = new Page(currentPage,pageSize);
        page = userMapper.selectPage(page,null);
        return page;
    }

@DS 能夠註解在方法上和類上,同時存在方法註解優先於類上註解

註解在service實現或mapper接口方法上,但強烈不建議同時在service和mapper註解。 (可能會有問題)

若是不加入主鍵則使用默認數據源。

DruidDataSourceAutoConfigure會注入一個DataSourceWrapper,其會在原生的spring.datasource下找url,username,password等。而咱們動態數據源的配置路徑是變化的,因此須要排除:

spring:
  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure

或者在類上排除:

@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)

而後更換properties配置信息:

#公共配置 Druid登陸帳號 密碼
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=123456
spring.datasource.dynamic.druid.initial-size=5
spring.datasource.dynamic.druid.min-idle=5
spring.datasource.dynamic.druid.maxActive=20
spring.datasource.dynamic.druid.maxWait=60000
spring.datasource.dynamic.druid.timeBetweenEvictionRunsMillis=60000
spring.datasource.dynamic.druid.minEvictableIdleTimeMillis=300000
spring.datasource.dynamic.druid.validationQuery=SELECT 1 FROM DUAL
spring.datasource.dynamic.druid.testWhileIdle=true
spring.datasource.dynamic.druid.testOnBorrow=false
spring.datasource.dynamic.druid.testOnReturn=false
spring.datasource.dynamic.druid.poolPreparedStatements=true
spring.datasource.dynamic.druid.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.dynamic.druid.filters=stat,slf4j
spring.datasource.dynamic.druid.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
spring.datasource.dynamic.druid.web-stat-filter.enabled=true
spring.datasource.dynamic.druid.web-stat-filter.url-pattern=/*
spring.datasource.dynamic.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*
spring.datasource.dynamic.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.dynamic.druid.stat-view-servlet.allow=127.0.0.1,192.168.163.1
spring.datasource.dynamic.druid.stat-view-servlet.deny=192.168.1.73
spring.datasource.dynamic.druid.stat-view-servlet.reset-enable=false

本篇代碼案例地址:

https://github.com/450255266/open-doubi

相關文章
相關標籤/搜索