版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cckevincyh/article/details/79187959
Spring Boot 整合多数据源
我们先创建一个maven项目:
创建两个数据库test01和test02,并且都创建一个user表
配置pom.xml
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cc.springboot</groupId>
<artifactId>springboot-many-mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
配置文件中新增两个数据源
application.properties
spring.datasource.test1.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test1.url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username = root
spring.datasource.test1.password = root
spring.datasource.test2.driverClassName = com.mysql.jdbc.Driver
spring.datasource.test2.url = jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username = root
spring.datasource.test2.password = root
创建分包Mapper
分包创建User1Mapper和User2Mapper
package com.cc.springboot.test01;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
public interface User1Mapper {
@Insert("insert into users values(#{id},#{username});")
public int addUser(@Param("id") Integer id, @Param("username") String username);
}
package com.cc.springboot.test02;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
public interface User2Mapper {
@Insert("insert into users values(#{id},#{username});")
public int addUser(@Param("id") Integer id, @Param("username") String username);
}
配置文件中新增两个数据源
package com.cc.springboot.datasource;
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.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration // 注册到springboot容器中
@MapperScan(basePackages = "com.cc.springboot.test01", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config {
/**
*配置test1数据库
*/
@Bean(name = "test1DataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.test1")
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
/*
* test1 sql会话工厂
*/
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// bean.setMapperLocations(
// new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
return bean.getObject();
}
/**
*test1 事物管理
*/
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test1SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package com.cc.springboot.datasource;
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.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration // 注册到springboot容器中
@MapperScan(basePackages = "com.cc.springboot.test02", sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSource2Config {
/**
*配置test2数据库
*/
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
/*
* test2 sql会话工厂
*/
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// bean.setMapperLocations(
// new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
return bean.getObject();
}
/**
*test2 事物管理
*/
@Bean(name = "test2TransactionManager")
public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
分包创建service
package com.cc.springboot.service.test01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.cc.springboot.test01.User1Mapper;
@Service
public class User1Service {
@Autowired
private User1Mapper user1Mapper;
public int addUser(Integer id, String name) {
return user1Mapper.addUser(id, name);
}
}
package com.cc.springboot.service.test02;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.cc.springboot.test02.User2Mapper;
@Service
public class User2Service {
@Autowired
private User2Mapper user2Mapper;
public int addUser(Integer id, String name) {
return user2Mapper.addUser(id, name);
}
}
创建Controller
package com.cc.springboot.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.cc.springboot.service.test01.User1Service;
import com.cc.springboot.service.test02.User2Service;
@RestController
public class IndexController {
@Autowired
private User1Service user1Service;
@Autowired
private User2Service user2Service;
@RequestMapping("/add")
public String index() {
user1Service.addUser(1,"db user001");
user2Service.addUser(2,"db user002");
return "success";
}
}
创建启动类
package com.cc.springboot.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {"com.cc.springboot.controller","com.cc.springboot.test01","com.cc.springboot.test02","com.cc.springboot.service","com.cc.springboot.datasource"})
@EnableAutoConfiguration
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
测试
启动:
注意事项
如果去掉DataSource1Config配置中的@Primary会发生什么??
发现报错了:
错误原因:No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: test1DataSource,test2DataSource
给其中一个数据源加上@Primary。因为在Spring Boot Jdbc的自动配置过程中,会对于开发者透明地使用dataSource进行一些相关配置,所以当有两个Datasource实现类时,Spring Boot将无法确定使用哪一个。
DataSource1Config配置中的注解的具体解释:
- @Primary:指定在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@Autowire注解报错(一般用于多数据源的情况下)
- @Qualifier:指定名称的注入,当一个接口有多个实现类的时候使用(在本例中,有两个DataSource类型的实例,需要指定名称注入)
- @Bean:生成的bean实例的名称是方法名(例如上边的@Qualifier注解中使用的名称是前边两个数据源的方法名,而这两个数据源也是使用@Bean注解进行注入的)