一、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);
}
}
我們這時的多數據源配置就完成了,只需要我們測試配置是否正確,我自己測試沒問題的,希望能給你們帶來幫助!
