在开发业务中可能因为数据量巨大,或者并发量大,又或者因为其他的种种原因,一个数据无法满足我们的需求,那么如何在同一个项目中配置多个数据库呢?下面就简单说一下简单的多数据源配置(这里都以mysql为例)
一、添加yml配置
相信单一数据源的配置大家都很熟悉,而多数据源的配置也非常简单,直接上码:

#读写分离的多数据源
#读库

  datasource:
    read:
      jdbc-url: jdbc:mysql:///mark_read?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver     
      
 #写库  
    write:
      jdbc-url: jdbc:mysql:///market?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver

可以看到为了方便区分,我再两个数据源的配置上分别以read和write来区分,当然,这不是绝对的,你也可以用test1,test2等等都可以,在接下来要说的配置类中需要通过指定这个配置来读取相关信息
二、增加配置类
为两个数据源分别增加配置,配置的时候用@Primary指定哪个是主库,一般如果是读写分离的话写为主库
1、数据源1

package com.wwy.config;

import javax.sql.DataSource;
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.core.io.support.PathMatchingResourcePatternResolver;
/**
 * 多数据源的数据源配置类(读)
 * @author wwy
 * @date 2019年12月12日
 * @version v0.0.1
 *
 * 配置数据源通常需要配置以下bean:
 * DataSource
 * SqlSessionFactory
 * SqlSessionTemplate
 */
@MapperScan(basePackages = "com.wwy.**.read",
sqlSessionFactoryRef = "readSqlSessionFactory")
@Configuration
public class ReadDataSourceConfig {

/**
 * 1.DataSource
 */
	//务必为bean添加名字,因为多数据源注入时需要按照名字注入,否则会引起冲突

	@Bean("readDataSource")
	//指定yml中配置的参数的前缀
	@ConfigurationProperties("spring.datasource.read")
	public DataSource readDataSource() {
		return DataSourceBuilder.create().build();
	}
	/**
	 * 2.SqlSessionFactory
	 * @throws Exception 
	 */

	@Bean("readSqlSessionFactory")
	public SqlSessionFactory readSqlSessionFactory(
			//这里注意:要按名称注入!
			@Qualifier("readDataSource")DataSource dataSource) throws Exception {
		SqlSessionFactoryBean ssf=new SqlSessionFactoryBean();
		//指定数据源
		ssf.setDataSource(dataSource);
		//指定xml位置
		ssf.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/read/*.xml")
				);
		return ssf.getObject();		
	}
	/**
	 * 3.SqlSessionTemplate
	 */	
	@Bean("readSqlSessionTemplate")
	public SqlSessionTemplate readSqlSessionTemplate(@Qualifier("readSqlSessionFactory")SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

2、数据源2

package com.wwy.config;

import javax.sql.DataSource;
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.core.io.support.PathMatchingResourcePatternResolver;
/**
 * 多数据源的数据源配置类(写)
 * @author wwy
 * @date 2019年12月12日
 * @version v0.0.1
 *
 * 配置数据源通常需要配置以下bean:
 * DataSource
 * SqlSessionFactory
 * SqlSessionTemplate
 */
@Primary
@Configuration
@MapperScan(basePackages = "com.wwy.**.write",
sqlSessionFactoryRef = "writeSqlSessionFactory")
public class WriteDataSourceConfig {

/**
 * 1.DataSource
 */
	//务必为bean添加名字,因为多数据源注入时需要按照名字注入,否则会引起冲突
	@Bean("writeDataSource")
	//指定yml中配置的参数的前缀
	@ConfigurationProperties("spring.datasource.write")
	public DataSource writeDataSource() {
		return DataSourceBuilder.create().build();
	}
	/**
	 * 2.SqlSessionFactory
	 * @throws Exception 
	 */
	@Bean("writeSqlSessionFactory")
	public SqlSessionFactory writeSqlSessionFactory(
			//这里注意:要按名称注入!
			@Qualifier("writeDataSource")DataSource dataSource) throws Exception {
		SqlSessionFactoryBean ssf=new SqlSessionFactoryBean();
		//指定数据源
		ssf.setDataSource(dataSource);
		//指定xml位置
		ssf.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/**/write/*.xml")
				);
		return ssf.getObject();		
	}
	/**
	 * 3.SqlSessionTemplate
	 */
	@Bean("writeSqlSessionTemplate")
	public SqlSessionTemplate writeSqlSessionTemplate(@Qualifier("writeSqlSessionFactory")SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}
}

三、使用
切记按照配置类中指定的mapper路径规则和xml路径规则,接下来就使我们常规的码代码了,这里就不再赘述!写完可以测试一下。
注意:1.如果出现org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)的异常,首先检查配置类中是否忘写@MapperScan(basePackages = "com.wwy.**.write", sqlSessionFactoryRef = "writeSqlSessionFactory")的注解,这个注解是必须写的,不要认为不写这个注解,直接在接口上添加@mapper注解就可以了,我试验是不可以的;其次是xml文件位置是否指定,然后是检查namespace的值是否正确;如果都没有问题,数据源是可以正常使用的!
2.在配置类中的bean必须指定名字,注入时也必须按照名字注入,防止冲突。