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);
    }
}

 

 

 

 

 

 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐