在项目中,随着业务复杂度提高,我们可能要同时操作多个数据库,这个时候我们就需要配置多个数据源了。这里做个笔记,以免忘记!!!
废话不说太多,直接上代码
项目结构
1.数据源配置文件
在application.yml配置文件中配置两个数据源,如下:
datasource:
pre :
jdbc-url: jdbc:mysql://localhost:3306/xiaxia1?useUnicode=true&characterEncoding=utf8&characterResultSets=utf8
username: root
password: 123456
sit :
jdbc-url: jdbc:mysql://localhost:3306/xiaxia2?useUnicode=true&characterEncoding=utf8&characterResultSets=utf8
username: root
password: 123456
注:按层次结构写的配置文件,一定要注意缩进以及表达的含义。
2.修改springboot服务启动文件:Application.java
//排除自动配置数据源
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
//自动扫描包路径下面的所有@Controller、@Service、@Repository、@Component 的类,
// 并把符合扫描规则的类装配到spring容器中。
@ComponentScan(basePackages = {"com.xiateng"})
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
配置说明:exclude = {DataSourceAutoConfiguration.class}
exclude,排除此类的AutoConfig,即禁止 SpringBoot 自动注入数据源配置,DataSourceAutoConfiguration.class 会自动查找 application.yml 或者 properties 文件里的 spring.datasource.* 相关属性并自动配置单数据源,因为这里我们需要手动配置多数据源
3.配置两个数据源(数据源个数看自己需要)
@Configuration
public class DataSourceConfig {
// 表示这个数据源是默认数据源
@Primary
// 将这个对象放入spring容器中(交给Spring管理)
@Bean(name="preDataSource")
// 读取 application.yml 中的配置参数映射成为一个对象
@ConfigurationProperties(prefix = "spring.datasource.pre")
public DataSource getDataSource1(){
// 创建一个数据源
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name="sitDataSource")
@ConfigurationProperties(prefix = "spring.datasource.sit")
public DataSource getDataSource2(){
return DataSourceBuilder.create().build();
}
}
/**
* 数据源Config1
*/
@Configuration
@MapperScan(basePackages = {"com.xiateng.dao.user"}, sqlSessionFactoryRef = "preSqlSessionFactory")
public class MybatisPreConfig {
@Autowired
@Qualifier("preDataSource")
private DataSource dataSource;
/**
* 创建 SqlSessionFactory
* @return
* @throws Exception
*/
@Bean(name="preSqlSessionFactory")
@Primary
// @Qualifier表示查找Spring容器中名字为 preDataSource 的对象
public SqlSessionFactory preSqlSessionFactory() throws Exception{
// 用来创建 SqlSessionFactory 等同于下面配置
// <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
// <property name="dataSource" ref="dataSource" />
// <property name="mapperLocations" value="classpath:mybatis-mapper/*.xml"/>
// </bean>
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 设置mybatis的xml所在位置(扫描mybatis的相关xml文件,装配到容器中)
bean.setMapperLocations(new PathMatchingResourcePatternResolver().
getResources("classpath*:com/xiateng/mapper/user/*.xml"));
return bean.getObject();
}
/**
* 通过 SqlSessionFactory 来创建 SqlSessionTemplate
* @param sqlSessionFactory
* @return
*/
@Bean(name="preSqlSessionTemplate")
@Primary
public SqlSessionTemplate preSqlSessionTemplate(@Qualifier("preSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
// SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用
return new SqlSessionTemplate(sqlSessionFactory);
}
}
/**
* 数据源Config2
*/
@Configuration
@MapperScan(basePackages = {"com.xiateng.dao.userbuyer"}, sqlSessionFactoryRef = "sitSqlSessionFactory")
public class MybatisSitConfig {
@Autowired
@Qualifier("sitDataSource")
private DataSource dataSource;
/**
* 创建 SqlSessionFactory
* @return
* @throws Exception
*/
@Bean(name="sitSqlSessionFactory")
// @Primary
public SqlSessionFactory sitSqlSessionFactory() throws Exception{
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// 设置mybatis的xml所在位置
bean.setMapperLocations(new PathMatchingResourcePatternResolver().
getResources("classpath*:com/xiateng/mapper/userbuyer/*.xml"));
return bean.getObject();
}
/**
* 通过 SqlSessionFactory 来创建 SqlSessionTemplate
* @param sqlSessionFactory
* @return
*/
@Bean(name="sitSqlSessionTemplate")
// @Primary
public SqlSessionTemplate sitSqlSessionTemplate(@Qualifier("sitSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
// SqlSessionTemplate是线程安全的,可以被多个DAO所共享使用
return new SqlSessionTemplate(sqlSessionFactory);
}
}
实现总结:1、启动类上排除SpringBoot对数据源的自动装配
2、application.yml配置文件配置多个数据源
3、通过注解@MapperScan将对应的dao指定对应的SqlSessionFactory
4、在调用对应dao方法的时候会调用相应的数据库,这样就完成了对多个数据库的操作
这样就简单的实现了多数据源,不过这种方式属于写死的操作,经过优化实现了数据源动态切换。。。