Springboot + Mybatis 多数据源配置

摘要:
1、 src/main/resources/application。在属性中配置多个数据源。春天datasourceInitialize=false#接口请求端口号和路径服务器端口=9090服务器。上下文路径=/#mybatis配置#mybatis。config locations=classpath:mybatis

1、src/main/resources/application.properties 中配置好多个数据源

  spring.datasource.initialize=false
  #接口请求端口号、路径
  server.port=9090
  servcer.context-path=/
  #mybatis配置
  #mybatis.config-locations=classpath:mybatis/mybatis-config.xml
  mybatis.mapper-locations=classpath:mapper/*.xml
  #oracle数据库数据源信息
  oracle.datasource.driverClassName=oracle.jdbc.OracleDriver
  oracle.datasource.url=jdbc:oracle:thin:@ip/dbname
  oracle.datasource.username=user
  oracle.datasource.password=pwd
  #mysql数据库数据源信息
  mysql.datasource.jdbc.driverClassName=com.mysql.jdbc.Driver
  mysql.datasource.jdbc.url=jdbc:mariadb://ip:3306/dbname
  mysql.datasource.jdbc.username=user
  mysql.datasource.jdbc.password=pwd

2、定义一个枚举类型 DatabaseType.java,表示不同的环境

  package com.twf.springBootDemo.util;

/**
 * @author tianwf
 * @date 2020/12/30 9:58
 * oracle oracle数据库环境
 * mysql mysql数据库环境
 */
public enum DatabaseType {
    oracle("oracle", "1"), mysql("mysql", "2");

    private String name;
    private String value;

    DatabaseType(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

3、定义一个 DatabaseContextHolder.java, 保存一个线程安全的DatabaseType容器

  package com.twf.springBootDemo.dataSourceConfig;

import com.twf.springBootDemo.util.DatabaseType;

/**
 * @author tianwf
 * @date 2020/12/30 10:00
 * 保存一个线程安全的DatabaseType容器
 */
public class DatabaseContextHolder {

    private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();

    public static void setDatabaseType(DatabaseType databaseType) {
        contextHolder.set(databaseType);
    }

    public static DatabaseType getDatabaseType() {
        return contextHolder.get();
    }
}

4、定义动态数据源获取的方法 DynamicDataSource.java,集成 AbstractRoutingDataSource

  package com.twf.springBootDemo.dataSourceConfig;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * @author tianwf
 * @date 2020/12/30 10:15
 * 动态数据源(需要继承AbstractRoutingDataSource)
 * 使用DatabaseContextHolder获取当前线程的DatabaseType
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DatabaseContextHolder.getDatabaseType();
    }
}

5、mybatis多数据源的配置 MybatisConfig.java

  package com.twf.springBootDemo.dataSourceConfig;

import com.alibaba.druid.pool.DruidDataSource;
import com.twf.springBootDemo.util.DatabaseType;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author tianwf
 * @date 2020/12/30 10:21
 * mybatis多数据源的配置,springboot集成mybatis基本入口
 * 1、创建数据源
 * 2、创建SqlSessionFactory
 */

@Configuration
@MapperScan(basePackages = "com.twf.springBootDemo.mapper", sqlSessionFactoryRef = "sessionFactory")
public class MybatisConfig {
    /*mapper.xml路径*/
    @Value("${mybatis.mapper-locations}")
    private String mapperPath;

    /*oracle驱动*/
    @Value("${oracle.datasource.driverClassName}")
    private String oradbDriver;

    /*oracle数据库连接地址*/
    @Value("${oracle.datasource.url}")
    private String oraUrl;

    /*oracle数据库连接用户名*/
    @Value("${oracle.datasource.username}")
    private String oraUsername;

    /*oracle数据库连接密码*/
    @Value("${oracle.datasource.password}")
    private String oraPassword;

    /*mysql驱动*/
    @Value("${mysql.datasource.jdbc.driverClassName}")
    private String mysqldbDriver;

    /*mysql数据库连接地址*/
    @Value("${mysql.datasource.jdbc.url}")
    private String mysqlUrl;

    /*mysql数据库连接用户名*/
    @Value("${mysql.datasource.jdbc.username}")
    private String mysqlUsername;

    /*mysql数据库连接密码*/
    @Value("${mysql.datasource.jdbc.password}")
    private String mysqlPassword;

    /**
     * 创建 oracle环境 dataSource
     * @throws Exception
     */
    @Bean(name = "dataSourceOracle")
    public DataSource dataSourceOracle() throws Exception {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(oradbDriver);
        dataSource.setUrl(oraUrl);
        dataSource.setUsername(oraUsername);
        dataSource.setPassword(oraPassword);

        return dataSource;
    }

    /**
     * 创建 mysql环境 dataSource
     * @throws Exception
     */
    @Bean(name="dataSourceMysql")
    public DataSource dataSourceMysql() throws Exception {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(mysqldbDriver);
        dataSource.setUrl(mysqlUrl);
        dataSource.setUsername(mysqlUsername);
        dataSource.setPassword(mysqlPassword);

        return dataSource;
    }

    /**
     * 1、创建动态数据源
     * @throws Exception
     * @Primary该注解表示在同一个接口有多个类可以注入的时候,默认选择哪个,而不是让@Autowired报错
     */
    @Bean(name="dynamicDataSource")
    @Primary
    public DynamicDataSource dynamicDataSource(
            @Qualifier("dataSourceOracle") DataSource dataSourceOracle,
            @Qualifier("dataSourceMysql") DataSource dataSourceMysql
    ) throws Exception {
        Map<Object, Object> targetDataSource = new HashMap<>();
        targetDataSource.put(DatabaseType.oracle, dataSourceOracle);
        targetDataSource.put(DatabaseType.mysql, dataSourceMysql);
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(targetDataSource);
        dynamicDataSource.setDefaultTargetDataSource(dataSourceOracle);

        return dynamicDataSource;
    }

    /**
     * 根据数据源创建SqlSessionFactory
     * @throws Exception
     */
    @Bean(name="sessionFactory")
    public SqlSessionFactory sessionFactory(
            @Qualifier("dynamicDataSource") DynamicDataSource dynamicDataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dynamicDataSource);
        PathMatchingResourcePatternResolver pmrpr = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(pmrpr.getResources(mapperPath));//*Mapper.xml位置

        return sqlSessionFactoryBean.getObject();
    }
}

6、修改服务类 StudentService.java:添加环境切换方法setDataSourceByEnvironment,同时在获取数据的方法中切换数据源

  package com.twf.springBootDemo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.twf.springBootDemo.dataSourceConfig.DatabaseContextHolder;
import com.twf.springBootDemo.entity.Customer;
import com.twf.springBootDemo.mapper.CustomerMapper;
import com.twf.springBootDemo.service.WebService;
import com.twf.springBootDemo.util.DatabaseType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@MapperScan("com.twf.springBootDemo.mapper")
public class WebServiceImpl implements WebService {

    @Resource
    private CustomerMapper customerMapper;

    public void setDataSourceByEnvironment(String environment) {
        //oracle数据源
        if(environment.equals(DatabaseType.oracle.getValue())) {
            DatabaseContextHolder.setDatabaseType(DatabaseType.oracle);
        } else if(environment.equals(DatabaseType.mysql.getValue())) {//mysql数据源
            DatabaseContextHolder.setDatabaseType(DatabaseType.mysql);
        }
    }

    @Override
    public String helloWorld(String params) {
        System.out.println("====" + params);
        setDataSourceByEnvironment("1");
        List<Customer> customerList = customerMapper.getCustomerList();
//        System.out.println(customerList.size());
        if(customerList.size() > 0) {
            for(int i = 0; i < customerList.size(); i++) {
                Customer customer = customerList.get(i);
                System.out.println(customer.getName());
            }
        }

        return result;
    }
}

7、SpringBoot配置多数据源,会引发循环引用问题

  修改方案:在Spring boot启动的时候排除DataSourceAutoConfiguration,并另外导入MyBatisConfig

  @Import({MybatisConfig.class})
  @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

免责声明:文章转载自《Springboot + Mybatis 多数据源配置》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇linux kernel系列四:嵌入式系统中的文件系统以及MTDAsp.net(asp,jsp)+JavaScript动态实现添加数据行下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

实现客户端程序自动更新使用FTP

 最近做的一个项目中需要用到客户端自动更新功能,最初的想法是利用ClickOnce技术来完成,但在实践中发现根本行不能,原因如下: 1)项目应用到了DevExpress控件包,用ClickOnce发布的自动更新程序,客户在安装时报在GAC中找不到控件dll的错。 2)ClickOnce安装无法实现根据用户安装时录入的参数(比如数据库服务器名、数据库用户名...

Java实现加密和解密的源代码

本文转载于网络,抄录下来只是为了方便以后查找。原文地址:http://snowolf.iteye.com/blog/379860 加密解密,曾经是我一个毕业设计的重要组件。在工作了多年以后回想当时那个加密、解密算法,实在是太单纯了。言归正传,这里我们主要描述Java已经实现的一些加密解密算法,最后介绍数字证书。如基本的单向加密算法: BASE64 严格...

java中String编码转换 UTF-8转GBK

1.GB2312等都可以用GBK代替.2.new String(row.getBytes("GB2312"), "UTF8") 这种写法是不对的, 中文仍然会乱码. 方案:解决GBK字符转UTF-8乱码问题: https://www.cnblogs.com/xijin-wu/p/5884822.html 彻底搞懂编码 GBK 和 UTF8:https:/...

SpringMVC之类型转换Converter

(转载:http://blog.csdn.net/renhui999/article/details/9837897) 1.1     目录 1.1      目录 1.2      前言 1.3      Converter接口 1.4      ConversionService接口 1.5      ConverterFactory接口 1.6   ...

ExcelTools使用

using NPOI.SS.Formula.Functions; using NPOI.SS.UserModel; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; nam...

IDEA 创建 MAPPER 模板

Mybatis 是一款优秀的 ORM 框架,但是在 IDEA 工具使用时并未自带 MAPPER 文件模板,需要手工添加,接下来就一起在 IDEA 中创建一个 MAPPER 文件模板吧; 1、打开 IDEA ,右键 new-->Edit File Template 2、点击 + ,输入此模板名称 3、黏贴 MAPPER 模板内容: <?xml...