springboot與mybatis和springmvc的整合


一、springboot項目的基本搭建

       相信大家都熟悉,不需要我多說,這里我用的是idea開發工具。

二、基本的配置

       我的項目目錄具體如下:

 

 

       1.一個項目最重要的是pom.xml文件,其中的依賴起着至關重要的作用,所以我們首先必須明白我們項目需要哪些依賴,這里我把我需要的依賴展示出來,供大家參考:

<?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>

    <groupId>com.wwd.frank</groupId>
    <artifactId>sunny-starter-core</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot_mybatisplus</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-jdbc</artifactId>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--添加jsp依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <!-- SpringBoot - MyBatis 逆向工程 -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!-- MyBatis 通用 Mapper -->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>1.1.4</version>
        </dependency>

        <!--新加的開始-->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>
        <dependency>
            <groupId>com.vaadin.external.google</groupId>
            <artifactId>android-json</artifactId>
            <version>0.0.20131108.vaadin1</version>
            <scope>compile</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/net.sourceforge.jexcelapi/jxl -->
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>jxl</artifactId>
            <version>2.6.12</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.9</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2.1-b03</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-cli</artifactId>
            <version>0.5.0.M5</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!--部署熱啟動依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <!--將resources目錄下的配置文件編譯進classes文件  -->
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <executions>
                    <execution>
                        <id>Generate MyBatis Artifacts</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.3.2</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>3.5.0</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>


</project>

  

       2.application.properties為項目的基本配置文件,包含數據源的配置和端口配置,還有其他一些參數配置等,具體如下:

server.port=8088
#spring.datasource.url=jdbc:mysql://localhost:3306/bamsdb?useUnicode=true&characterEncoding=utf-8&useSSL=false
#spring.datasource.url=jdbc:mysql://localhost:3306/bamsdb?characterEncoding=utf-8&useSSL=false
#spring.datasource.username=bams
#spring.datasource.password=Bams@123
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#spring.datasource.hikari.login-timeout=1000
#spring.datasource.hikari.maximum-pool-size=30


#數據源one
spring.datasource.one.name=oneDatasource
spring.datasource.one.jdbc-url=jdbc:mysql://localhost:3306/bamsdb?characterEncoding=utf-8&useSSL=false
spring.datasource.one.username=bams
spring.datasource.one.password=Bams@123
spring.datasource.one.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.one.hikari.login-timeout=1000
spring.datasource.one.hikari.maximum-pool-size=30


#數據源two
spring.datasource.two.name=twoDatasource
spring.datasource.two.jdbc-url=jdbc:mysql://localhost:3306/bamsdb?characterEncoding=utf-8&useSSL=false
spring.datasource.two.username=bams
spring.datasource.two.password=Bams@123
spring.datasource.two.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.two.hikari.login-timeout=1000
spring.datasource.two.hikari.maximum-pool-size=30

mybatis.mapper-locations=classpath:com/wwd/frank/dao/mapper/*.xml

  被注釋的是單數據源配置,下面的兩個配置one、two為多數據源配置。

       3.generatorConfig.xml為數據庫反向生成的配置文件,可以生成dao層、entity層、service層和mapper.xml層,具體配置內容為:

          

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!--mysql 連接數據庫jar 這里選擇自己本地位置-->
    <classPathEntry location="C:\Users\john\.m2\repository\mysql\mysql-connector-java\5.1.30\mysql-connector-java-5.1.30.jar" />
    <context id="testTables" targetRuntime="MyBatis3">
        <!-- 實現序列化 -->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
        <commentGenerator>
            <!-- 是否去除自動生成的注釋 true:是 : false:否 -->
            <property name="suppressAllComments" value="false" />
        </commentGenerator>
        <!--數據庫連接的信息:驅動類、連接地址、用戶名、密碼 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/bamsdb"
                        userId="bams"
                        password="Bams@123">
        </jdbcConnection>

        <!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true
         時把JDBC DECIMAL 和
           NUMERIC 類型解析為java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>



        <!--  生成的路徑及名稱  -->
        <!-- 生成模型(PO)的包名和位置 -->
        <javaModelGenerator targetPackage="com.wwd.frank.entity" targetProject="src/main/java">
            <!-- enableSubPackages:是否讓schema作為包的后綴 -->
            <property name="enableSubPackages" value="false" />
            <!-- 從數據庫返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!-- 生成映射文件的包名和位置-->
        <sqlMapGenerator targetPackage="com.wwd.frank.dao.mapper" targetProject="src">
            <!-- enableSubPackages:是否讓schema作為包的后綴 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>

        <!-- 生成DAO的包名和位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.wwd.frank.dao" targetProject="src/main/java">
            <!-- enableSubPackages:是否讓schema作為包的后綴 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>


        <!-- 列出要生成代碼的所有表,這里配置的是不生成Example文件 只需要改tableName(表名)和 domainObjectName(實體名)-->
        <table tableName="fap_user" domainObjectName="User"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"></table>

    </context>
</generatorConfiguration>

  這里需要我們改對應的mysql-connector-java-5.1.30.jar地址、數據源參數、生成文件路徑及數據源表名等。

       啟動項目后,在項目的右邊欄中找到maven_projects菜單,點擊進去找到Plugin下的mybatis-generator,然后雙擊mybatis-generator:generate,如果程序不報錯,並且有生成的dao層包、.xml文件、entity包及對應的實體,說明反向生成建模成功,我們的配置沒問題。

4.線程池的配置

4.1首先我們要知道有哪些線程池: 

a.newCachedThreadPool,是一種線程數量不定的線程池,並且其最大線程數為Integer.MAX_VALUE,這個數是很大的,一個可緩存線程池,如果線程池長度                 超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。但是線程池中的空閑線程都有超時限制,這個超時時長是60秒,超過60秒閑置線程就會被                   回收。調用execute將重用以前構造的線程(如果線程可用)。這類線程池比較適合執行大量的耗時較少的任務,當整個線程池都處於閑置狀態時,線程池中的                   線程都會超時被停止。

b.newFixedThreadPool 創建一個指定工作線程數量的線程池,每當提交一個任務就創建一個工作線程,當線程 處於空閑狀態時,它們並不會被回收,除非線                   程池被關閉了,如果工作線程數量達到線程池初始的最大數,則將提交的任務存入到池隊列(沒有大小限制)中。由於newFixedThreadPool只有核心線程                     並且這些核心線程不會被回收,這樣它更加快速底相應外界的請求。

c.newScheduledThreadPool 創建一個線程池,它的核心線程數量是固定的,而非核心線程數是沒有限制的,並且當非核心線程閑置時會被立即回收,它可安                   排給定延遲后運行命令或者定期地執行。這類線程池主要用於執行定時任務和具有固定周期的重復任務。

d.newSingleThreadExecutor這類線程池內部只有一個核心線程,以無界隊列方式來執行該線程,這使得這些任務之間不需要處理線程同步的問題,它確保所                     有的任務都在同一個線程中按順序中執行,並且可以在任意給定的時間不會有多個線程是活動的。

4.2 在這里,我們使用newCachedThreadPool來創建線程池,在目錄文件configs下的TaskPoolConfig類中配置,如下:

                 

                

TaskPoolConfig.java的具體代碼如下:
package com.wwd.frank.configs;

import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * 線程池配置類
 */
@EnableAsync
@Configuration
public class TaskPoolConfig {

    private int corePoolSize = 10;//線程池維護線程的最少數量

    private int maxPoolSize = 100;//線程池維護線程的最大數量

    private int queueCapacity = 8; //緩存隊列

    private int keepAlive = 60;//允許的空閑時間

    private int waitAlive = 60;//允許的等待時間

    @Bean("taskExecutor")
    public Executor myExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        //線程名前綴
        executor.setThreadNamePrefix("taskExecutor-");
        // rejection-policy:當pool已經達到max size的時候,如何處理新任務
        // CALLER_RUNS:不在新線程中執行任務,而是由調用者所在的線程來執行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //對拒絕task的處理策略
        executor.setKeepAliveSeconds(keepAlive);
        executor.setAwaitTerminationSeconds(waitAlive);
        executor.initialize();
        return executor;
    }
}

線程池配置完成,下面需要我們使用了。

4.3 定時任務執行引用線程池,文件所在目錄,如下:

我們在Task文件下創建Task.java類,在類里創建我幾個方法,每個方法都利用了線程池的操作,在PoolTask.java類中定義定時任務,執行操作,代碼如下:

Task.java類的代碼:

package com.wwd.frank.task.poolTask;

import com.wwd.frank.entity.User;
import groovy.util.logging.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Random;

/**
 *
 * 利用線程池做定時任務
 */
@Slf4j
@Component
public class Task {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    public static Random random = new Random();
    @Autowired
    private com.wwd.frank.dao.mapper.UserMapper usermapper;
    @Async("taskExecutor")
    public void doTaskOne() throws Exception {
        logger.info("doTaskOne   *********  開始做任務一,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        List<User> list = usermapper.findAll();
        logger.info("************************查詢到的數據為:"+list.toString());
        logger.info("doTaskOne   *********  完成任務一,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskTwo() throws Exception {
        logger.info("doTaskTwo   *********  開始做任務二,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskTwo   *********  完成任務二,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskThree() throws Exception {
        logger.info("doTaskThree   *********  開始做任務三,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskThree   *********  完成任務三,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskFour() throws Exception {
        logger.info("doTaskFour   *********  開始做任務四,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskFour   *********  完成任務四,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskFive() throws Exception {
        logger.info("doTaskFive   *********  開始做任務五,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskFive   *********  完成任務五,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskSix() throws Exception {
        logger.info("doTaskSix   *********  開始做任務六,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskSix   *********  完成任務六,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskSeven() throws Exception {
        logger.info("doTaskSeven   *********  開始做任務七,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskSeven   *********  完成任務七,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskEight() throws Exception {
        logger.info("doTaskEight   *********  開始做任務八,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskEight   *********  完成任務八,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskNine() throws Exception {
        logger.info("doTaskNine   *********  開始做任務九,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskNine   *********  完成任務九,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }

    @Async("taskExecutor")
    public void doTaskTen() throws Exception {
        logger.info("doTaskTen   *********  開始做任務十,線程名為:"+ Thread.currentThread().getName());
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        logger.info("doTaskTen   *********  完成任務十,耗時:" + (end - start) + "毫秒,線程名為:"+ Thread.currentThread().getName());
    }
}

PoolTask.java類的代碼:

package com.wwd.frank.task.poolTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 利用線程池執行異步定時任務
 */
@Component
public class PoolTask {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private Task task;
    /**
     * 每隔一秒執行一次
     */
    @Scheduled(fixedRate =5000)
    public void logTime() throws Exception {
        logger.info("**********************線程池的定時任務開始執行**********************");
        task.doTaskOne();
        task.doTaskTwo();
        task.doTaskThree();
        task.doTaskFour();
        task.doTaskFive();
        task.doTaskSix();
        task.doTaskSeven();
        task.doTaskEight();
        task.doTaskNine();
        task.doTaskTen();
        //在多線程編程中,Thread.CurrentThread 表示獲取當前正在運行的線程,join方法是阻塞當前調用線程,直到某線程完全執行才調用線程繼續執行,
        //如果獲取的當前線程是主線程,調用Join方法,當前的線程會阻塞住,因為線程無法結束
//        Thread.currentThread().join();
    }
}

特別注意的是,不建議使用Thread.currentThread().join(),因為可能會引起線程阻塞的情況發生。

 5.多數據源的配置使用

你應該注意到,在開始的時候,application.properties中有多個數據源的配置,就是在項目中引用多數據源,滿足我們項目的多數據庫的操作。

首先,在application.properties中配置我們需要到的數據庫參數,具體如下:

server.port=8088
#數據源one
spring.datasource.one.name=oneDatasource
spring.datasource.one.jdbc-url=jdbc:mysql://localhost:3306/bamsdb?characterEncoding=utf-8&useSSL=false
spring.datasource.one.username=bams
spring.datasource.one.password=Bams@123
spring.datasource.one.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.one.hikari.login-timeout=1000
spring.datasource.one.hikari.maximum-pool-size=30


#數據源two
spring.datasource.two.name=twoDatasource
spring.datasource.two.jdbc-url=jdbc:mysql://localhost:3306/bamsdb?characterEncoding=utf-8&useSSL=false
spring.datasource.two.username=bams
spring.datasource.two.password=Bams@123
spring.datasource.two.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.two.hikari.login-timeout=1000
spring.datasource.two.hikari.maximum-pool-size=30

mybatis.mapper-locations=classpath:com/wwd/frank/dao/mapper/*.xml

配置中的參數名字必須對應上,版本不一致,參數名可能匹配不上,所以要特別注意了。

然后,在文件包moreDataResources下創建兩個對應的數據源配置類,目錄如下:

 

                      DataResourceOne.java類中配置數據源one,DataResourceTwo.java配置數據源two,具體如下:

                      DataResourceOne.java類的代碼:

package com.wwd.frank.moreDataResources;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 數據源one
 */
@Configuration
@MapperScan(basePackages = "com.wwd.frank.dao.mapper", sqlSessionTemplateRef = "oneSqlSessionTemplate")
public class DataResourceOne {
    /**
     * 配置數據數據源 master
     *
     * @return
     */
    @Bean(name = "oneDatasource")
    @ConfigurationProperties(prefix = "spring.datasource.one")
    @Primary
    public DataSource masterDatasource() {
        return DataSourceBuilder.create().build();
    }

    /**
     * 配置session工廠
     *
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name = "oneSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("oneDatasource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
//        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:"));
        return bean.getObject();
    }


    /**
     * 配置事務管理器
     *
     * @param dataSource
     * @return
     */
    @Bean(name = "oneTransactionManger")
    @Primary
    public DataSourceTransactionManager masterTransactionManger(@Qualifier("oneDatasource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    /**
     * 模版
     *
     * @param sqlSessionFactory
     * @return
     * @throws Exception
     */
    @Bean(name = "oneSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 DataResourceTwo.java類的代碼:

package com.wwd.frank.moreDataResources;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
/**
 * 數據源two
 */
@Configuration
@MapperScan(basePackages = "com.wwd.frank.dao.mapperTwo" ,sqlSessionTemplateRef = "twoSqlSessionTemplate")
public class DataResourceTwo {
    /**
     * 配置數據數據源 slave
     * @return
     */
    @Bean(name = "twoDatasource")
    @ConfigurationProperties(prefix = "spring.datasource.two")
//    @Primary
    public DataSource slaveDatasource(){
        return DataSourceBuilder.create().build();
    }

    /**
     * 配置session工廠
     * @param dataSource
     * @return
     * @throws Exception
     */
    @Bean(name = "twoSqlSessionFactory")
    //    @Primary
    public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("twoDatasource") DataSource dataSource) throws  Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        //        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:"));
        return bean.getObject();
    }


    /**
     * 配置事務管理器
     * @param dataSource
     * @return
     */
    @Bean(name = "twoTransactionManger")
    //    @Primary
    public DataSourceTransactionManager slaveTransactionManger(@Qualifier("twoDatasource") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }


    /**
     * 模版
     * @param sqlSessionFactory
     * @return
     * @throws Exception
     */
    @Bean(name = "twoSqlSessionTemplate")
    //    @Primary
    public SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("twoSqlSessionFactory")SqlSessionFactory sqlSessionFactory) throws Exception{
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

                    對應的兩個配置類中,注解@MapperScan(basePackages = "com.wwd.frank.dao.mapperTwo" ,sqlSessionTemplateRef = "twoSqlSessionTemplate")

                     需要特別注意,basePackages 包路徑是對應的Mapper.xml文件路徑,每種數據源對應一個Mapper.xml文件,在我們使用時,在server實現層中只需要引用我們想用的數據庫對應的Mapper.java接口類就可以達到需求,這里不需要對其實現,我們的項目是默認允許自動生成實現類。

            

 配置完成后,我們只需要在server的實現類中注入Mapper.java接口類就可以了。

以User為例,UserServiceImp.java實現類中如何引用不同的數據源的代碼如下:

package com.wwd.frank.service.imp;
import com.wwd.frank.entity.User;
import com.wwd.frank.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class UserServiceImp implements UserService {

    @Autowired
    private com.wwd.frank.dao.mapper.UserMapper userMapper;
    @Autowired
    private com.wwd.frank.dao.mapperTwo.UserMapperTwo userMapperTwo;
    @Override
    public List<User> findAll() {
        return userMapper.findAll();
    }

    @Override
    public List<User> findTestAll() {
        return userMapperTwo.findAllTwo();
    }

    @Override
    public int insertSelective(User record) {
        return userMapper.insert(record);
    }
}

        我們這時的多數據源配置就完成了,只需要我們測試配置是否正確,我自己測試沒問題的,希望能給你們帶來幫助!

 

 

 

         

 

          

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM