Spring Boot Mybatis数据库datasource多数据源配置
application.yaml文件配置spring:datasource:db1:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://192.168.0.1:3306/ellassay_dev?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBe
application.yaml文件配置
spring:
datasource:
db1:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://192.168.0.1:3306/db1?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
username: yeyuanxinyi
password: 123456
db2:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://192.168.0.2:3306/db2?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
username: yeyuanxiner
password: 123456
这里有个坑需要注意下,在单数据源配置中数据库地址属性名为url,改成多数据源配置后要改成jdbc-url,否则会报jdbcUrl is required with driverClassName错误
Caused by: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:951)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:157)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:323)
at org.springframework.boot.jdbc.EmbeddedDatabaseConnection.isEmbedded(EmbeddedDatabaseConnection.java:123)
at org.springframework.boot.jdbc.AbstractDataSourceInitializer.isEnabled(AbstractDataSourceInitializer.java:74)
at org.springframework.boot.jdbc.AbstractDataSourceInitializer.initialize(AbstractDataSourceInitializer.java:54)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:363)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:307)
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:136)
... 18 common frames omitted
数据源相关Bean注入配置
数据源1配置,关键点看配置代码中的注释
- DataSource依赖于application.yaml中的配置
- SqlSessionFactory依赖DataSource
- SqlSessionTemplate依赖SqlSessionFactory
- @MapperScan注解的basePackages属性为Mapper文件包名
- @MapperScan注解的sqlSessionTemplateRef属性值为注入的SqlSessionTemplate对象
- SqlSessionFactoryBean的setMapperLocations方法设置xml Mapper文件路径
- 注意这里注入的事务管理对象DataSourceTransactionManager在此处未使用到,可以在@Transactional(value = "dataSourceTransactionManager1")注解中使用
@Configuration
// basePackages为对应的Mapper文件包名,sqlSessionTemplateRef为注入的SqlSessionTemplate对象bean名
@MapperScan(basePackages = "com.yeyuanxinyi.mapper1", sqlSessionTemplateRef = "sqlSessionTemplate1")
public class DB1Config {
@Bean(name = "dataSource1") // 注入的数据源bean名
@ConfigurationProperties(prefix = "spring.datasource.db1") // application.yaml中的数据源配置
@Primary
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
// 以上面注入的DataSource对象dataSource1为参数
@Bean(name = "sqlSessionFactory1")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource1") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// xml Mapper文件路径
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper1/*Mapper.xml"));
return bean.getObject();
}
// 以上面注入的DataSource对象dataSource1为参数
@Bean(name = "dataSourceTransactionManager1") // 该bean作为@Transactional注解的参数,用法@Transactional(value = "dataSourceTransactionManager1")
@Primary
public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("dataSource1") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
// 以上面注入的SqlSessionFactory对象sqlSessionFactory1为参数
@Bean(name = "sqlSessionTemplate1") // 作为上面@MapperScan注解的sqlSessionTemplateRef属性的值
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
数据源2配置,与数据源1配置类似,只是依赖的application.yaml中的db2配置,而且注入的相关bean名字不同
@Configuration
// basePackages为对应的Mapper文件包名,sqlSessionTemplateRef为注入的SqlSessionTemplate对象bean名
@MapperScan(basePackages = "com.yeyuanxinyi.mapper2", sqlSessionTemplateRef = "sqlSessionTemplate2")
public class DB2Config {
@Bean(name = "dataSource2") // 注入的数据源bean名
@ConfigurationProperties(prefix = "spring.datasource.db2") // application.yaml中的数据源配置
@Primary
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
// 以上面注入的DataSource对象dataSource2为参数
@Bean(name = "sqlSessionFactory2") // 该bean作为@Transactional注解的参数,用法@Transactional(value = "sqlSessionFactory2")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource2") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// xml Mapper文件路径
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper2/*Mapper.xml"));
return bean.getObject();
}
// 以上面注入的DataSource对象dataSource2为参数
@Bean(name = "dataSourceTransactionManager2") // 该bean作为@Transactional注解的参数,用法@Transactional(value = "dataSourceTransactionManager2")
@Primary
public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("dataSource2") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
// 以上面注入的SqlSessionFactory对象sqlSessionFactory2为参数
@Bean(name = "sqlSessionTemplate2") // 作为上面@MapperScan注解的sqlSessionTemplateRef属性的值
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
java Mapper文件
db1对应的Mapper java文件存放在com.yeyuanxinyi.mapper1包下
public interface StudentMapper {
List<Student> getAll();
Student get(Long id);
void insert(Student);
void update(Student);
void delete(Long id);
}
db2对应的Mapper java文件存放在com.yeyuanxinyi.mapper2包下
public interface TeacherMapper {
List<Teacher> getAll();
Teacher get(Long id);
void insert(Teacher);
void update(Teacher);
void delete(Long id);
}
xml Mapper文件
db1对应的Mapper xml文件存放在resources/mapper1路径下
db2对应的Mapper xml文件存放在resources/mapper2路径下
具体的文件代码就不贴了,注意文件名与对应的java mapper文件名同名即可,如
- StudentMapper.xml
- TeacherMapper.xml
Service
由于DB1Config中配置了@MapperScan(basePackages = "com.yeyuanxinyi.mapper1"),而StudentMapper在com.yeyuanxinyi.mapper1包下,所以StudentMapper使用数据源db1
@Transactional(value = "dataSourceTransactionManager1")中dataSourceTransactionManager1关联的是数据源db1,所以当发生异常时回滚db1
@Service()
// 这里传入DB1Config中注入配置注入的dataSourceTransactionManager1对象
@Transactional(rollbackFor = Exception.class, value = "dataSourceTransactionManager1")
public class StudentService {
@Resource()
private StudentMapper studentMapper;
public List<Student> getAll() {
return studentMapper.getAll();
}
public Student get(Long id) {
return studentMapper.get();
}
public void insert(Teacher teacher) {
studentMapper.insert(teacher);
}
public void update(Teacher teacher) {
studentMapper.update(teacher);
}
public void delete(Long id) {
studentMapper.delete(id);
}
}
由于DB2Config中配置了@MapperScan(basePackages = "com.yeyuanxinyi.mapper2"),而TeacherMapper在com.yeyuanxinyi.mapper2包下,所以TeacherMapper使用数据源db2
@Transactional(value = "dataSourceTransactionManager2")中dataSourceTransactionManager2关联的是数据源db2,所以当发生异常时回滚db2
@Service()
// 这里传入DB2Config中注入配置注入的dataSourceTransactionManager2对象
@Transactional(rollbackFor = Exception.class, value = "dataSourceTransactionManager2")
public class TeacherService {
@Resource()
private TeacherMapper teacherMapper;
public List<Teacher> getAll() {
return teacherMapper.getAll();
}
public Teacher get(Long id) {
return teacherMapper.get();
}
public void insert(Teacher teacher) {
teacherMapper.insert(teacher);
}
public void update(Teacher teacher) {
teacherMapper.update(teacher);
}
public void delete(Long id) {
teacherMapper.delete(id);
}
}
更多推荐
所有评论(0)