1.背景
最近的项目需要同步另外一个数据库的数据,因此开始捣鼓springboot双(多)数据库的配置。参考了很多博客和手册,顺便整理了自己的项目,成功运行并。
2.思路
专门画个图,方便理解
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SNxEDO1ETM5EjY0UWM1ITNzYzXwQTMwYTMxIzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
3.按图走起,follow me
3.1 pom.xml添加一些依赖
<!-- oracle依赖 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0</version>
</dependency>
<!-- Mysql依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 数据池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
3.2 application.properties配置两个数据源
server.port=8080
master.datasource.url=jdbc:oracle:thin:@//233.233.233.233:1521/xjyj
master.datasource.username=数据库用户名
master.datasource.password=数据库密码
master.datasource.driverClassName=oracle.jdbc.driver.OracleDriver
second.datasource.url=jdbc:mysql://localhost:3306/hoava?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
second.datasource.username=数据库用户名
second.datasource.password=数据库密码
second.datasource.driverClassName=com.mysql.cj.jdbc.Driver
3.3 数据源的配置
注意:多数据源配置的时候,数据源应该有主次之分,需要有一个主数据源,我们配置MasterDataSourceConfig为主数据源
MasterDataSourceConfig.java
1.@Primary表示这个Bean如果有多个同类Bean候选时,优先考虑。(多数据源配置必须有主数据源,用@Primary表示该Bean)
2.@MapperScan 扫描 Mapper 接口并容器管理,包路径精确到 master(一定注意精确到的包路径,否则出现binding exception)
3.@Value 获取全局配置文件 application.properties 的 kv 配置,并自动装配。sqlSessionFactoryRef 表示定义了 key ,表示一个唯一 SqlSessionFactory 实例
@Configuration //配置注解
@MapperScan(basePackages = MasterDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
static final String PACKAGE = "com.dock.dao.master";
static final String MAPPER_LOCATION = "classpath:mapper/master/*.xml";
@Value("${master.datasource.url}")
private String url;
@Value("${master.datasource.username}")
private String user;
@Value("${master.datasource.password}")
private String password;
@Value("${master.datasource.driverClassName}")
private String driverClass;
@Bean(name = "masterDataSource")
@Primary
public DataSource masterDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager masterTransactionManager() {
return new DataSourceTransactionManager(masterDataSource());
}
@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(masterDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(MasterDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
}
SecondDataSourceConfig.java
@Configuration
@MapperScan(basePackages = SecondDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfig {
static final String PACKAGE = "com.dock.dao.second";
static final String MAPPER_LOCATION = "classpath:mapper/second/*.xml";
@Value("${second.datasource.url}")
private String url;
@Value("${second.datasource.username}")
private String user;
@Value("${second.datasource.password}")
private String password;
@Value("${second.datasource.driverClassName}")
private String driverClass;
@Bean(name = "secondDataSource")
public DataSource clusterDataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUrl(url);
dataSource.setUsername(user);
dataSource.setPassword(password);
return dataSource;
}
@Bean(name = "secondTransactionManager")
public DataSourceTransactionManager clusterTransactionManager() {
return new DataSourceTransactionManager(clusterDataSource());
}
@Bean(name = "secondSqlSessionFactory")
public SqlSessionFactory clusterSqlSessionFactory(@Qualifier("secondDataSource") DataSource clusterDataSource)
throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(clusterDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(SecondDataSourceConfig.MAPPER_LOCATION));
return sessionFactory.getObject();
}
}
4.走正常流程:
4.1service层
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TestDao testDao;
@Autowired
private TestDaoTwo testDaoTwo;
@Override
public List testCon() {
List<v_t_xk_by_yjskc> list = testDao.testCon();
System.out.println("============第一个数据库");
System.out.println(list);
List list1 = testDaoTwo.testDaoTwo();
System.out.println("============第二个数据库");
System.out.println(list1);
List listall = new ArrayList();
listall.add(list);
listall.add(list1);
return listall;
}
}
4.2dao层
目录结构如图
TesDao
@Repository
@Mapper
public interface TestDao {
List testCon();
}
TesDaoTwo
@Repository
@Mapper
public interface TestDaoTwo {
List testDaoTwo();
}
4.3 Mapper
4.4 Controller
@Controller
@RequestMapping(value = "/test")
public class testController {
@Autowired
private TestService testService;
@ResponseBody
@RequestMapping("/te1")
public Map<String, Object> testCon1(){
Map<String,Object> result = new HashMap<>();
result.put("two",testService.testCon());
return result;
}
}
4.5启动入口配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) //去除默认datasource配置
@ServletComponentScan
public class DockApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DockApplication.class, args);
}
}
5.最终结果如图:
目录结构如图