1、准备依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2、准备数据源
在application.properties中配置两个数据源,这里可以配置多个数据源,为了演示方便,我配置了两个数据源。
#数据源1
spring.datasource.db1.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.db1.jdbc-url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
spring.datasource.db1.username = root
spring.datasource.db1.password = 12345
#数据源2
spring.datasource.db2.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.db2.jdbc-url = jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
spring.datasource.db2.username = root
spring.datasource.db2.password = 12345
3、数据源配置
这里需要配置两个数据源。
3.1、配置数据源1
/**
* @author 小吉
* @description 数据源配置1
* @date 2020/6/17
*/
@Configuration
@MapperScan(basePackages = "com.springbootdemo12.mapper.db1", sqlSessionFactoryRef = "sqlSessionFactory1")
public class DSConfig1 {
@Bean(name = "dataSource1")
@ConfigurationProperties(prefix = "spring.datasource.db1")
@Primary
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "sqlSessionFactory1")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource1") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "transactionManager1")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource1") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionTemplate1")
@Primary
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
3.2、配置数据源2
/**
* @author 小吉
* @description 数据源配置1
* @date 2020/6/17
*/
@Configuration
@MapperScan(basePackages = "com.springbootdemo12.mapper.db2", sqlSessionFactoryRef = "sqlSessionFactory2")
public class DSConfig2 {
@Bean(name = "dataSource2")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "sqlSessionFactory2")
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource2") DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
return bean.getObject();
}
@Bean(name = "transactionManager2")
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "sqlSessionTemplate2")
public SqlSessionTemplate sqlSessionTemplate(
@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
3.3、启动类配置
/**
* @author 小吉
* @description springboot启动类
* @date 2020/6/17
*/
@MapperScan(basePackages = {"com.springbootdemo12.mapper"})
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
数据源配置类DSConfig1、DSConfig1都需要和启动类在同级包下或者在启动类所在包的子级包中。
4、准备Mapper
由于我在依赖中加入的数据库组件是mybatis,所以需要准备两个不同mapper。
/**
* @author 小吉
* @description
* @date 2020/6/17
*/
public interface UserMapper1 {
@Insert("insert into t_user values(null,#{name},#{age});")
public int save(@Param("name") String name,@Param("age") Integer age);
@Delete("delete from t_user where name = #{name}")
public void deleteByName(@Param("name")String name);
}
/**
* @author 小吉
* @description
* @date 2020/6/17
*/
public interface UserMapper2 {
@Select("select id,name,age from t_user where name=#{name}")
public Map getUserByName(@Param("name") String name);
}
UserMapper1、UserMapper2必须要在启动类中指定的扫描包com.springbootdemo12.mapper下。
5、单元测试
/**
* @author 小吉
* @description SpringBoot整合多数据源
* @date 2020/6/17
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class MutileDataSourceTest {
@Autowired
private UserMapper1 userMapper1;
@Autowired
private UserMapper2 userMapper2;
@Autowired
private UserService userService;
@Test
public void testSave(){
userMapper1.save("zhangsan",7);
}
@Test
public void testGet(){
Map map = userMapper2.getUserByName("王二狗");
System.out.println("name = " + map.get("name") + ",age = " + map.get("age"));
}
}
5.1、使用数据源1插入记录
5.2、使用数据源2查询记录
6、多数据源事务问题
6.1、Transactional注解
/**
* @author 小吉
* @description
* @date 2020/6/17
*/
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper1 userMapper1;
@Transactional(transactionManager = "transactionManager1")
@Override
public void doSave(String name, int age) {
userMapper1.deleteByName(name);
userMapper1.save(name,age);
//throw new RuntimeException("error");
}
}
/**
* @author 小吉
* @description SpringBoot整合多数据源
* @date 2020/6/17
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class MutileDataSourceTest {
@Autowired
private UserMapper1 userMapper1;
@Autowired
private UserMapper2 userMapper2;
@Autowired
private UserService userService;
@Test
public void testSave(){
userMapper1.save("zhangsan",7);
}
@Test
public void testGet(){
Map map = userMapper2.getUserByName("王二狗");
System.out.println("name = " + map.get("name") + ",age = " + map.get("age"));
}
@Test
public void testTran(){
userService.doSave("zhangsan",9);
}
}
在多数据源使用的情况下,需要注意下事务问题。加上Transactional注解的时候,注意的是需要指定一下transactionManager。