请耐心看完
注意:本示例用的是springboot2.0
你们在项目中有使用到多数据源吗?
原理使用根据包名,加载不同的数据源,也可以根据注解加载不同的数据源
直接奔向主题,请系好安全带!!!
配置两个不同的数据源
#datasource1
spring.datasource.test1.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test1.jdbc-url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username = root
spring.datasource.test1.password = root
spring.datasource.test1.min-pool-size = 3
spring.datasource.test1.max-pool-size = 25
spring.datasource.test1.max-lifetime = 20000
spring.datasource.test1.borrow-connection-timeout = 30
spring.datasource.test1.login-timeout = 30
spring.datasource.test1.maintenance-interval = 60
spring.datasource.test1.max-idle-time = 60
#datasource2
spring.datasource.test2.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test2.jdbc-url = jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username = root
spring.datasource.test2.password = root
spring.datasource.test2.min-pool-size = 3
spring.datasource.test2.max-pool-size = 25
spring.datasource.test2.max-lifetime = 20000
spring.datasource.test2.borrow-connection-timeout = 30
spring.datasource.test2.login-timeout = 30
spring.datasource.test2.maintenance-interval = 60
spring.datasource.test2.max-idle-time = 60
别着急,先看一下项目结构
可以看到定义了两个mapper包,放不同的业务
配置类分别加载两个数据源,这里都是写死的,可以直接copy来用噢
package cn.ly.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.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.jdbc.datasource.DataSourceTransactionManager;
//配置01数据源
//这是一个配置文件
@Configuration
//指定cn.ly.service1包用test1数据源,test1SqlSessionFactory下面有配置
@MapperScan(basePackages = "cn.ly.mapper1", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config {
/**
*
* @methodDesc: 功能描述:(配置test1数据库)
* @author: Ly
*/
@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test1")
@Primary
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
/**
*
* @methodDesc: 功能描述:(test1 sql会话工厂)
* @author: Ly
*/
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//这里可以指定扫描mapper文件
// bean.setMapperLocations(
// new
// PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
return bean.getObject();
}
/**
*
* @methodDesc: 功能描述:(test1 事物管理)
* @author: Ly
*/
@Bean(name = "test1TransactionManager")
@Primary
public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package cn.ly.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.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
//配置e02数据源
//这是一个配置文件
@Configuration
//指定cn.ly.service1包用test2数据源,test2SqlSessionFactory下面有配置
@MapperScan(basePackages = "cn.ly.mapper2", sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSource2Config {
/**
*
* @methodDesc: 功能描述:(配置test2数据库)
* @author: Ly
*/
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource testDataSource() {
return DataSourceBuilder.create().build();
}
/**
*
* @methodDesc: 功能描述:(test2 sql会话工厂)
* @author: Ly
*/
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//这里可以指定扫描mapper文件
// bean.setMapperLocations(
// new
// PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
return bean.getObject();
}
/**
*
* @methodDesc: 功能描述:(test2 事物管理)
* @author: Ly
*/
@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);
}
}
看清除噢,这里主要说明了哪个mapper包用哪个数据源
Mapper层
Service层
分别调用不懂的mapper
Controller层
附上我的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>cn.ly</groupId>
<artifactId>SpringBootDataSource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mysql依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- springboot-web组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
</project>
ok完事,看懂的麻烦点个赞
<<<<-------------------------------------------------------完美的分割线------------------------------------------------------->>>>
多数据源事物管理
设问:如果我们使用多数据源的时候,某个方法引用了多个个数据源,那我操作失败的时候如何回滚呢?
这个时候我们就需要整合我们的多数据源事物了
使用springboot+jta+atomikos 分布式事物管理
atomikos 是一个为Java平台提供增值服务的并且开源类事务管理器。
项目结构图:
新增jta-atomikos依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
新增配置文件信息
#datasource1
spring.datasource.test1.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test1.jdbc-url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8
spring.datasource.test1.username = root
spring.datasource.test1.password = root
spring.datasource.test1.min-pool-size = 3
spring.datasource.test1.max-pool-size = 25
spring.datasource.test1.max-lifetime = 20000
spring.datasource.test1.borrow-connection-timeout = 30
spring.datasource.test1.login-timeout = 30
spring.datasource.test1.maintenance-interval = 60
spring.datasource.test1.max-idle-time = 60
#datasource2
spring.datasource.test2.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test2.jdbc-url = jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8
spring.datasource.test2.username = root
spring.datasource.test2.password = root
spring.datasource.test2.min-pool-size = 3
spring.datasource.test2.max-pool-size = 25
spring.datasource.test2.max-lifetime = 20000
spring.datasource.test2.borrow-connection-timeout = 30
spring.datasource.test2.login-timeout = 30
spring.datasource.test2.maintenance-interval = 60
spring.datasource.test2.max-idle-time = 60
读取配置文件信息
@Data
@ConfigurationProperties(prefix = "spring.datasource.test1")
public class DBConfig1 {
private String jdbcUrl;
private String username;
private String password;
private int minPoolSize;
private int maxPoolSize;
private int maxLifetime;
private int borrowConnectionTimeout;
private int loginTimeout;
private int maintenanceInterval;
private int maxIdleTime;
private String testQuery;
}
@Data
@ConfigurationProperties(prefix = "spring.datasource.test2")
public class DBConfig2 {
private String jdbcUrl;
private String username;
private String password;
private int minPoolSize;
private int maxPoolSize;
private int maxLifetime;
private int borrowConnectionTimeout;
private int loginTimeout;
private int maintenanceInterval;
private int maxIdleTime;
private String testQuery;
}
创建多数据源,这个类也需要改变,但是改变幅度不大
package cn.ly.dataSource;
import java.sql.SQLException;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
import cn.ly.DBConfig.DBConfig1;
//配置DataSource01数据源
//这是一个配置文件
@Configuration
//指定cn.ly.service1包用test1数据源,test1SqlSessionFactory下面有配置
@MapperScan(basePackages = "cn.ly.mapper1", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config {
/**
*
* @methodDesc: 功能描述:(配置test1数据库)
* @author: Ly
* @throws SQLException
*/
@Bean(name = "test1DataSource")
@Primary
public DataSource testDataSource(DBConfig1 testConfig) throws SQLException {
MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
mysqlXaDataSource.setUrl(testConfig.getJdbcUrl());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
mysqlXaDataSource.setPassword(testConfig.getPassword());
mysqlXaDataSource.setUser(testConfig.getUsername());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("test1DataSource");
xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
xaDataSource.setTestQuery(testConfig.getTestQuery());
return xaDataSource;
}
/**
*
* @methodDesc: 功能描述:(test1 sql会话工厂)
* @author: Ly
*/
@Bean(name = "test1SqlSessionFactory")
@Primary
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//这里可以指定扫描mapper文件
// bean.setMapperLocations(
// new
// PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml"));
return bean.getObject();
}
@Bean(name = "test1SqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
package cn.ly.dataSource;
import java.sql.SQLException;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.atomikos.jdbc.AtomikosDataSourceBean;
import com.mysql.jdbc.jdbc2.optional.MysqlXADataSource;
import cn.ly.DBConfig.DBConfig2;
//配置DataSource02数据源
//这是一个配置文件
@Configuration
//指定cn.ly.service1包用test2数据源,test2SqlSessionFactory下面有配置
@MapperScan(basePackages = "cn.ly.mapper2", sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSource2Config {
/**
*
* @methodDesc: 功能描述:(配置test2数据库)
* @author: Ly
* @throws SQLException
*/
@Bean(name = "test2DataSource")
public DataSource testDataSource(DBConfig2 testConfig) throws SQLException {
MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
mysqlXaDataSource.setUrl(testConfig.getJdbcUrl());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
mysqlXaDataSource.setPassword(testConfig.getPassword());
mysqlXaDataSource.setUser(testConfig.getUsername());
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("test2DataSource");
xaDataSource.setMinPoolSize(testConfig.getMinPoolSize());
xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize());
xaDataSource.setMaxLifetime(testConfig.getMaxLifetime());
xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout());
xaDataSource.setLoginTimeout(testConfig.getLoginTimeout());
xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval());
xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime());
xaDataSource.setTestQuery(testConfig.getTestQuery());
return xaDataSource;
}
/**
*
* @methodDesc: 功能描述:(test2 sql会话工厂)
* @author: Ly
*/
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
//这里可以指定扫描mapper文件
// bean.setMapperLocations(
// new
// PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml"));
return bean.getObject();
}
@Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
主要改变的地方就是testDataSource方法和去掉了DataSourceTransactionManager创建事物的方法
还需要再启动类中
@EnableConfigurationProperties(value = { DBConfig1.class, DBConfig2.class })
加载这两个配置类
ok,我们测试一下
完全没问题,完事!!!
项目代码下载:https://download.csdn.net/download/qq_36125138/10764047