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);
    }
}

        我们这时的多数据源配置就完成了,只需要我们测试配置是否正确,我自己测试没问题的,希望能给你们带来帮助!

         

 

          

       

猜你喜欢

转载自www.cnblogs.com/frankdong/p/10318082.html