上一篇博文介绍了JdbcTemplate、Mybatis在Spring Boot中如何使用,但是都只是配置了一个数据源,下面小七给大家介绍一下,如何配置使用多个数据源。
其实,按照目前的分布式系统设计,咱们会按业务划分模块,每一个系统模块会使用自己的数据库,也就是说基本上不存在一个应用使用多个数据源的场景。但是有的数据报表,可能会从不同的模块获取数据,这个时候可能就要连接多个数据源了;不过这种情况也有办法解决,可以用其它的技术手段代替解决,比如先把数据都抽取到同一个数据库,这样就不需要跨库查询了,大大提升性能。另外,还有分库分表的问题,这个后面再来研究一下。
好了,下面小七给大家分别介绍一下JdbcTemplate和Mybatis如何配置多数据源:
(一)配置文件多数据源配置
首先,小七先贴出.yml中的配置,如下:
spring:
datasource:
test:
jdbc-url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=yes&characterEncoding=UTF8&allowMultiQueries=true
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver
test2:
jdbc-url: jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=yes&characterEncoding=UTF8&allowMultiQueries=true
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver
test和test2分别代表两个数据源。
(二)DataSource配置
接下来,再看看DataSource的配置,只需要新增一个配置类即可,代码如下:
package org.qyk.springboot.config;
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 javax.sql.DataSource;
/**
* <Change to the actual description of this class>
*
* @version 1.0
* <pre>
* Author Date Changes
* yongkang.qi 2020年04月05日 Created
*
* </pre>
* @since 1.7
*/
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.test")
@Primary
DataSource dsTest() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.test2")
DataSource dsTest2() {
return DataSourceBuilder.create().build();
}
}
dsTest和dsTest2分别代表各自的数据源。然后,@ConfigurationProperties(prefix = “spring.datasource.test”)这个配置,也应该看得懂,就是指定此数据源加载的属性名前缀。 @Primary是表示有个数据源的时候,得指定一个主的数据源,决定默认使用哪一个数据源。
(三)JdbcTemplate多数据源配置
好了,上面已经配置好了多个数据源,那么相应的JdbcTemplate也会有多个,每个都需要指定使用哪一个数据源,下面小七直接贴出代码,如下:
package org.qyk.springboot.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
/**
* <Change to the actual description of this class>
*
* @version 1.0
* <pre>
* Author Date Changes
* yongkang.qi 2020年04月05日 Created
*
* </pre>
* @since 1.7
*/
@Configuration
public class JdbcTemplateConfig {
@Bean
JdbcTemplate jdbcTemplateTest(@Qualifier("dsTest") DataSource dsTest) {
return new JdbcTemplate(dsTest);
}
@Bean
JdbcTemplate jdbcTemplateTest2(@Qualifier("dsTest2") DataSource dsTest2) {
return new JdbcTemplate(dsTest2);
}
}
jdbcTemplateTest和jdbcTemplateTest2,咱们在使用的时候,就可以区分开了。
下面,再来看看怎么使用,代码如下:
package org.qyk.springboot.dao3.impl;
import org.qyk.springboot.dao3.PersonDao;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* <Change to the actual description of this class>
*
* @version 1.0
* <pre>
* Author Date Changes
* yongkang.qi 2020年04月05日 Created
*
* </pre>
* @since 1.7
*/
@Repository
public class PersonDaoImpl implements PersonDao {
@Resource(name = "jdbcTemplateTest")
private JdbcTemplate template;
@Resource(name = "jdbcTemplateTest2")
private JdbcTemplate template2;
@Override
public List<Map<String, Object>> queryList(String userName) {
String sql = "SELECT * FROM person WHERE username LIKE ?";
List<Map<String, Object>> maps = template.queryForList(sql, userName);
return maps;
}
@Override
public List<Map<String, Object>> queryListByDataSource2(String userName) {
String sql = "SELECT * FROM person WHERE username LIKE ?";
List<Map<String, Object>> maps = template2.queryForList(sql, userName);
return maps;
}
}
查库的时候,想查询哪个库,就选择相应的JdbcTemplate即可。
(四)Mybatis多数据源配置
这里一样,也是需要先配置好多个数据源的,和上面一样,这里就不再重新说了。
接下来,小七直接先贴出两个配置类。
MybatisMultiDsTestConfig.java:
package org.qyk.springboot.config;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* <Change to the actual description of this class>
*
* @version 1.0
* <pre>
* Author Date Changes
* yongkang.qi 2020年04月05日 Created
*
* </pre>
* @since 1.7
*/
@Configuration
@MapperScan(basePackages = "org.qyk.springboot.dao", sqlSessionTemplateRef = "testSqlSessionTemplate")
public class MybatisMultiDsTestConfig {
@Bean
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("dsTest") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test/*.xml"));
bean.setTypeAliasesPackage("org.qyk.springboot.entity");
return bean.getObject();
}
@Bean
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("dsTest") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
@Primary
public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
MybatisMultiDsTest2Config.java:
package org.qyk.springboot.config;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* <Change to the actual description of this class>
*
* @version 1.0
* <pre>
* Author Date Changes
* yongkang.qi 2020年04月05日 Created
*
* </pre>
* @since 1.7
*/
@Configuration
@MapperScan(basePackages = "org.qyk.springboot.dao2", sqlSessionTemplateRef = "testSqlSessionTemplate2")
public class MybatisMultiDsTest2Config {
@Bean
public SqlSessionFactory testSqlSessionFactory2(@Qualifier("dsTest2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
bean.setTypeAliasesPackage("org.qyk.springboot.entity");
return bean.getObject();
}
@Bean
public DataSourceTransactionManager testTransactionManager2(@Qualifier("dsTest2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public SqlSessionTemplate testSqlSessionTemplate2(@Qualifier("testSqlSessionFactory2") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
@MapperScan的basePackages,就是表示Mapper接口类放到的包路径,sqlSessionTemplateRef用来指定这些Mapper接口对应Mapper.xml文件的SQL操作所使用的sqlSessionTemplate,也就是会使用哪个数据源。
同时,SqlSessionTemplate要使用哪个SqlSessionFactory,以及SqlSessionFactory要使用哪个DataSource、DataSourceTransactionManager事务管理要使用哪个DataSource,都需要指定。
因为basePackages指定了Mapper接口的包路径,那这些接口类就可以不需要@Mapper注解了。
然后mybatis相关的配置,比如mapper.xml文件都需要重新指定了,还要放到对应数据源的目录下面。
好啦,上面就是所有的配置啦,可以发现这样并不灵活,如果有很多数据源呢,那岂不是要加很多配置类么?哈哈,技术的发展都是朝着怎么简单、怎么方便来,所以根本不用担心,很多时候,当你觉得配置很繁琐的时候,那只是你没有接触一些新的技术或者解决办法,所以咱们学IT的,得多尝试多问~