针对“springboot mybatis调用多个数据源引发的错误问题”,我可以提供如下的攻略过程:
问题背景
在使用SpringBoot和Mybatis框架进行数据源操作时,可能会遇到需要多个数据源的情况,比如:读取或写入的数据源不同,或者需要连接不同的数据库等情况。在这种情况下,我们需要自定义DataSource,同时配置多个SqlSessionFactory和TransactionManager,并且需要在Mapper类上指定使用的数据源名称。但是很多开发者在操作时可能会遇到相关的错误问题,这也是我们本次攻略的重点。
解决方案
1. 自定义多数据源
自定义多数据源需要做如下几点准备:
- 定义多个DataSource,可以通过@Configuration和@Bean的方式注入;
- 分别配置多个SqlSessionFactory,并且指定使用的DataSource;
- 分别配置多个TransactionManager,并且指定使用的DataSource;
- 使用MapperScannerConfigurer扫描指定包下的Mapper类,并指定使用的SqlSessionFactory;
- 在Mapper类上使用@Qualifier注解指定使用的DataSource名称。
示例代码如下:
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test1", sqlSessionTemplateRef = "test1SqlSessionTemplate")
public class DataSource1Config {
@Primary
@Bean(name = "test1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test1")
public DataSource test1DataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "test1SqlSessionFactory")
public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource test1DataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(test1DataSource);
return bean.getObject();
}
@Primary
@Bean(name = "test1TransactionManager")
public DataSourceTransactionManager test1TransactionManager(@Qualifier("test1DataSource") DataSource test1DataSource) {
return new DataSourceTransactionManager(test1DataSource);
}
@Primary
@Bean(name = "test1SqlSessionTemplate")
public SqlSessionTemplate test1SqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory test1SqlSessionFactory) throws Exception {
return new SqlSessionTemplate(test1SqlSessionFactory);
}
}
@Configuration
@MapperScan(basePackages = "com.example.demo.mapper.test2", sqlSessionTemplateRef = "test2SqlSessionTemplate")
public class DataSource2Config {
@Bean(name = "test2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.test2")
public DataSource test2DataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "test2SqlSessionFactory")
public SqlSessionFactory test2SqlSessionFactory(@Qualifier("test2DataSource") DataSource test2DataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(test2DataSource);
return bean.getObject();
}
@Bean(name = "test2TransactionManager")
public DataSourceTransactionManager test2TransactionManager(@Qualifier("test2DataSource") DataSource test2DataSource) {
return new DataSourceTransactionManager(test2DataSource);
}
@Bean(name = "test2SqlSessionTemplate")
public SqlSessionTemplate test2SqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory test2SqlSessionFactory) throws Exception {
return new SqlSessionTemplate(test2SqlSessionFactory);
}
}
2. 指定Mapper使用的数据源
为了解决调用多个数据源引发的错误问题,我们需要在Mapper类上明确指定使用的数据源,这可以通过在Mapper类上添加@Qualifier注解实现,如下所示:
public interface TestMapper {
@Qualifier("test1DataSource")
@Select("SELECT * FROM test1 WHERE id = #{id}")
Test1 getTest1ById(@Param("id") Integer id);
@Qualifier("test2DataSource")
@Select("SELECT * FROM test2 WHERE id = #{id}")
Test2 getTest2ById(@Param("id") Integer id);
}
这样,每个方法都可以明确使用哪个数据源,Mybatis也可以正确地根据指定的DataSource进行数据源切换,避免错误的引用。
示例
我们假设我们需要创建两个数据库test1和test2,每个数据库中都有一个表,分别是test1和test2。下面我们就演示如何通过上述的自定义多数据源和指定Mapper使用的数据源方案,来实现多数据源的操作。
1. 环境搭建
- 创建两个数据库test1和test2,分别创建test1数据源和test2数据源,并在两个数据源中分别插入一些测试数据。
- 在Maven工程中添加如下依赖:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
2. 创建实体类和Mapper类
为了演示需要,我们需要在test1和test2中,各创建一个实体类和Mapper类。
test1实体类:
@Data
public class Test1 {
private Integer id;
private String name;
}
test1 Mapper类:
public interface Test1Mapper {
@Select("SELECT * FROM test1 WHERE id = #{id}")
Test1 getTest1ById(@Param("id") Integer id);
}
test2实体类:
@Data
public class Test2 {
private Integer id;
private String name;
}
test2 Mapper类:
public interface Test2Mapper {
@Select("SELECT * FROM test2 WHERE id = #{id}")
Test2 getTest2ById(@Param("id") Integer id);
}
3. 创建Controller类
我们创建一个TestController类,提供如下接口:
- /test1/{id}:获取test1中指定id的数据;
- /test2/{id}:获取test2中指定id的数据。
@RestController
public class TestController {
@Autowired
private Test1Mapper test1Mapper;
@Autowired
private Test2Mapper test2Mapper;
@GetMapping("/test1/{id}")
public Test1 getTest1ById(@PathVariable Integer id) {
return test1Mapper.getTest1ById(id);
}
@GetMapping("/test2/{id}")
public Test2 getTest2ById(@PathVariable Integer id) {
return test2Mapper.getTest2ById(id);
}
}
4. 配置多数据源
在我们的application.properties文件中添加如下配置:
# DataSource1
spring.datasource.test1.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.test1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.test1.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test1.username=root
spring.datasource.test1.password=root
spring.datasource.test1.initialSize=10
spring.datasource.test1.minIdle=5
spring.datasource.test1.maxActive=50
spring.datasource.test1.validationQuery=SELECT 1 FROM DUAL
spring.datasource.test1.testWhileIdle=true
spring.datasource.test1.testOnBorrow=false
spring.datasource.test1.testOnReturn=false
spring.datasource.test1.poolPreparedStatements=true
spring.datasource.test1.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.test1.filters=wall,stat
# DataSource2
spring.datasource.test2.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.test2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.test2.url=jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test2.username=root
spring.datasource.test2.password=root
spring.datasource.test2.initialSize=10
spring.datasource.test2.minIdle=5
spring.datasource.test2.maxActive=50
spring.datasource.test2.validationQuery=SELECT 1 FROM DUAL
spring.datasource.test2.testWhileIdle=true
spring.datasource.test2.testOnBorrow=false
spring.datasource.test2.testOnReturn=false
spring.datasource.test2.poolPreparedStatements=true
spring.datasource.test2.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.test2.filters=wall,stat
5. 启动运行
现在,我们可以直接运行应用程序,并使用如下地址进行访问:
- http://localhost:8080/test1/1
- http://localhost:8080/test2/1
分别对test1和test2进行获取数据操作,验证我们的多数据源操作是否生效。
总结
以上就是相关攻略的详细讲解,需要特别注意的是,在实际应用中,可能还需要配置多个数据库连接池,并且需要考虑到安全性、性能等因素,需要根据实际情况进行调整。同时也需要指出的是,Mybatis-plus等工具类在多数据源环境下的使用会更加简单方便,可以考虑使用相应的工具类来进行操作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot mybatis调用多个数据源引发的错误问题 - Python技术站