1.依赖包
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<!-- mybatis驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<!-- mybatis驱动包-->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>21.1.0.0</version>
</dependency>
<!-- 控制多数据源事务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
<version>2.7.2</version>
</dependency>
2.数据库驱动配置
3.创建数据源
3.1Oracle数据源
/**
* xxx对应扫描mapper包路径
*/
@Configuration
@MapperScan(basePackages = "com.xxx.xxx.xxx", sqlSessionTemplateRef = "ds1SqlSessionTemplate")
public class Ds1DataSource {
@Value("${spring.datasource.ds1.jdbc-url}")
private String jdbcUrl;
@Value("${spring.datasource.ds1.password}")
private String password;
@Value("${spring.datasource.ds1.username}")
private String username;
/**
* 将数据数据源交给jta管理
* @return
*/
@Primary
@Bean(name = "dataSource1")
public DataSource dataSource() throws SQLException {
OracleXADataSource oracleXADataSource = new OracleXADataSource();
oracleXADataSource.setURL(jdbcUrl);
oracleXADataSource.setPassword(password);
oracleXADataSource.setUser(username);
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(oracleXADataSource);
xaDataSource.setUniqueResourceName("dataSource1");
return xaDataSource;
}
//主数据源 ds1数据源
@Primary
@Bean("ds1SqlSessionFactory")
public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("dataSource1") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/xxx/xxx/**/mapper/*.xml"));
return sqlSessionFactory.getObject();
}
/**
* 不可以注册DataSourceTransactionManager类,注册该类后会使事务失效
* @param sqlSessionFactory
* @return
*/
// @Primary
// @Bean(name = "ds1TransactionManager")
// public DataSourceTransactionManager ds1TransactionManager(@Qualifier("dataSource1") DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
@Primary
@Bean(name = "ds1SqlSessionTemplate")
public SqlSessionTemplate ds1SqlSessionTemplate(@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
3.2mysql数据源
/**
* xxx对应扫描mapper路径
*/
@Configuration
@MapperScan(basePackages = "com.xxx.xxx.xxx.xxx", sqlSessionTemplateRef = "ds2SqlSessionTemplate")
public class Ds2DataSource {
@Value("${spring.datasource.ds2.jdbc-url}")
private String jdbcUrl;
@Value("${spring.datasource.ds2.password}")
private String password;
@Value("${spring.datasource.ds2.username}")
private String username;
/**
* 将数据数据源交给jta管理
* @return
*/
@Bean(name = "dataSource2")
// @ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSource dataSource() {
MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource();
// 设置连接信息
mysqlXaDataSource.setUrl(jdbcUrl);
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
mysqlXaDataSource.setPassword(password);
mysqlXaDataSource.setUser(username);
mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true);
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSource(mysqlXaDataSource);
xaDataSource.setUniqueResourceName("dataSource2");
return xaDataSource;
}
@Bean("ds2SqlSessionFactory")
public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("dataSource2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/xxx/xxx/xxx/**/mapper/*.xml"));
return sqlSessionFactory.getObject();
}
// @Bean(name = "ds2TransactionManager")
// public DataSourceTransactionManager ds2TransactionManager(@Qualifier("dataSource2") DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
@Bean(name = "ds2SqlSessionTemplate")
public SqlSessionTemplate ds2SqlSessionTemplate(@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
4.使用事务
4.1spring处理事务
//直接使用spring的Transactional注解处理事务
@Override
@Transactional(rollbackFor = Exception.class)
public void autoTransactionTest() {
/**
*业务代码
*/
}
4.2编程式事
4.2.1编程事务工具类
/**
* 手动控制事务
*/
@Component
public class TransactionManagerUtil {
//必须使用jta的事务管理器
private final JtaTransactionManager transactionManager;
public TransactionManagerUtil(JtaTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
/**
* 获取事务管理器
*
* @return
*/
public TransactionStatus getTransactionStatus() {
DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
return transactionManager.getTransaction(defaultTransactionDefinition);
}
/**
* 提交事务
*
* @param status
*/
public void commit(TransactionStatus status) {
transactionManager.commit(status);
}
/**
* 回滚事务
* @param status
*/
public void rollback(TransactionStatus status) {
transactionManager.rollback(status);
}
}
4.2.2编程式事务使用
@Autowired
private TransactionManagerUtil transactionManagerUtil;
@Override
public void nonAutoTransactionTest() {
TransactionStatus status = transactionManagerUtil.getTransactionStatus();
try {
/**
* 业务代码
*/
transactionManagerUtil.commit(status);
} catch (Exception e) {
log.error("运行出现异常", e);
transactionManagerUtil.rollback(status);
}
}