1.配置多数据源后需要注意的地方

2.配置说明

目录

1.配置多数据源后需要注意的地方

2.配置说明


多数据源的实现方法比较多,基于springboot和mybatis的情况下,有基于AOP进行动态数据源配置的实现,也有直接通过配置不同的SqlSessionFactory去扫描不同Mapper.xml目录去实现,也有通过dynamic-datasource-spring-boot-starter去实现。此外,还有通过各种第三方开源组件例如ShardingSphere实现的多数据源配置。本文着重介绍通过不同的SqlSessionFactory去实现多数据源配置。

1.配置多数据源后需要注意的地方

Springboot配置MybatisPlus(或Mybaits)多数据源后,常见的功能使用可能需要关注几个地方。

1.1数据源配置变化

eg:

单数据源

多数据源

数据源url

spring.datasource.url

spring.datasource.one.jdbc-url

...

1.2 分页问题

使用多数据源后,分页可能会失效,这个时候需要重新往SqlSessionFactory注册分页拦截器。从MyBatis-Plus 3.4.0开始,不再使用旧版本的PaginationInterceptor ,而是使用MybatisPlusInterceptor。

首先配置分页拦截器Bean

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 
 * @Description // 多数据源配置时,多种配置会失效。
 * 例如mybatisplus分页插件、数据库字段下换线自动转驼峰格式失效
 * @Date 2023/5/10
 **/
@Configuration
public class MyBatisPlusConfig {

    /**
     * mybatis-plus分页插件
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 向MyBatis-Plus的过滤器链中添加分页拦截器,需要设置数据库类型(主要用于分页方言)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

然后将分页拦截器配置到SqlSessionFactory

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @Author wengguochao@163.com
 * @Description // 配置mybatis的SessionFactory和SessionTemplate
 * @Date 2023/5/10
 **/
@Configuration
@MapperScan(value = "com.wgc.springboottest.dao.db1",sqlSessionFactoryRef = "sqlSessionFactoryBeanOne")
public class MybatisConfigOne {

    @Resource
    @Qualifier("dsOne")
    DataSource dsOne;

    @Resource
    private MybatisPlusInterceptor mybatisPlusInterceptor;

    @Bean
    SqlSessionFactory sqlSessionFactoryBeanOne() throws Exception {

        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dsOne);
        mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/db1/**/*.xml"));

        // 多数据源控制台打印sql,配置任意一个数据源即可
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
        mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);

        // 设置分页插件
        mybatisSqlSessionFactoryBean.setPlugins(mybatisPlusInterceptor);

        return mybatisSqlSessionFactoryBean.getObject();
    }

    @Bean
    SqlSessionTemplate sqlSessionTemplate1() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryBeanOne());
    }
}

1.3 IDEA控制台不打印Sql日志

多数据源需要手动配置SQL打印,选择任意一个SqlSessionFactoryBean注册日志打印即可。代码请参考1.2代码块

2.配置说明

Maven配置部分说明:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.11</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.wgc</groupId>
	<artifactId>springboottest</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboottest</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	

		<!--MybatisPlus引入-->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.5.3</version>
		</dependency>

		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<version>8.0.31</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.8.16</version>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>

	</build>


</project>

2.1配置DataSource

import com.zaxxer.hikari.HikariDataSource;
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 javax.sql.DataSource;

/**
 * @Author wengguochao@163.com
 * @Description //
 * @Date 2023/5/10
 **/
@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.one")
    public DataSource dsOne(){
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
//        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.two")
    public DataSource dsTwo(){
//        return DataSourceBuilder.create().type(HikariDataSource.class).build();
        return DataSourceBuilder.create().build();
    }


}

2.2 Springboot配置文件配置数据源信息

#mybatis多数据源
spring.datasource.one.jdbc-url=jdbc:mysql://10.xx.12.xx:3339/testSys?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
spring.datasource.one.username=root
spring.datasource.one.password=123456
spring.datasource.one.driver-class-name=com.mysql.cj.jdbc.Driver

#mybatis多数据源[springboot2.x 多数据源源需要注意url和driver-class与单数据源的区别]
spring.datasource.two.jdbc-url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
#spring.datasource.two.jdbc-url=jdbc:mysql://10.xx.12.xx:3340/testSys?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true
spring.datasource.two.username=root
spring.datasource.two.password=123456
spring.datasource.two.driver-class-name=com.mysql.cj.jdbc.Driver

2.3配置SqlSessionFactoryBean、分页插件

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @Author wengguochao@163.com
 * @Description // 配置mybatis的SessionFactory和SessionTemplate
 * @Date 2023/5/10
 **/
@Configuration
@MapperScan(value = "com.wgc.springboottest.dao.db1",sqlSessionFactoryRef = "sqlSessionFactoryBeanOne")
public class MybatisConfigOne {

    @Resource
    @Qualifier("dsOne")
    DataSource dsOne;

    @Resource
    private MybatisPlusInterceptor mybatisPlusInterceptor;

    @Bean
    SqlSessionFactory sqlSessionFactoryBeanOne() throws Exception {

        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dsOne);
        mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/db1/**/*.xml"));

        // 多数据源控制台打印sql,配置任意一个数据源即可
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
        mybatisSqlSessionFactoryBean.setConfiguration(mybatisConfiguration);

        // 设置分页插件
        mybatisSqlSessionFactoryBean.setPlugins(mybatisPlusInterceptor);

        return mybatisSqlSessionFactoryBean.getObject();
    }

    @Bean
    SqlSessionTemplate sqlSessionTemplate1() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryBeanOne());
    }
}



import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @Author wengguochao@163.com
 * @Description // 配置mybatis的SessionFactory和SessionTemplate
 * @Date 2023/5/10
 **/
@Configuration
@MapperScan(value = "com.wgc.springboottest.dao.db2",sqlSessionFactoryRef = "sqlSessionFactoryBeanTwo")
public class MybatisConfigTwo {

    @Resource
    @Qualifier("dsTwo")
    DataSource dsTwo;

    @Resource
    private MybatisPlusInterceptor mybatisPlusInterceptor;

    @Bean
    SqlSessionFactory sqlSessionFactoryBeanTwo() throws Exception {
        MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        mybatisSqlSessionFactoryBean.setDataSource(dsTwo);
        mybatisSqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/db2/**/*.xml"));

        // 设置分页插件
        mybatisSqlSessionFactoryBean.setPlugins(mybatisPlusInterceptor);
        return mybatisSqlSessionFactoryBean.getObject();
    }

    @Bean
    SqlSessionTemplate sqlSessionTemplate2() throws Exception {
        return new SqlSessionTemplate(sqlSessionFactoryBeanTwo());
    }
}



import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author wengguochao@163.com
 * @Description // 多数据源配置时,多种配置会失效。
 * 例如mybatisplus分页插件、数据库字段下换线自动转驼峰格式失效
 * @Date 2023/5/10
 **/
@Configuration
public class MyBatisPlusConfig {

    /**
     * mybatis-plus分页插件
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 向MyBatis-Plus的过滤器链中添加分页拦截器,需要设置数据库类型(主要用于分页方言)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

至此,基本配置就完成了。需要注意的是,SqlSessionFactoryBean创建的时候,指定了扫描指定的Mapper.xml目录,这个需要自行调整即可。至于Controller、Service、Dao层,就跟平时单数据源那样使用即可,比较简单,此处不做进一步论述。