一、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);
}
}
我们这时的多数据源配置就完成了,只需要我们测试配置是否正确,我自己测试没问题的,希望能给你们带来帮助!
