• 【Spring boot】双数据源/多数据源 spring boot+druid配置多数据源详细配置


    1.pom.xml文件

    <spring.boot.version>2.2.5.RELEASE</spring.boot.version>
    <mysql-connector-java-version>6.0.6</mysql-connector-java-version>
    <alibaba-druid-version>1.1.10</alibaba-druid-version>
    
    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</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-aop</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
            </dependency>
    </dependencies>

    2.启动类

    // 这个就不需要在启动类加了,相比较单数据源  @MapperScan("com.swapping.dao.mapper.mysql")
    @SpringBootApplication
    @ComponentScan(basePackages = {"com.swapping.*"})
    @Slf4j
    public class SwappingApiApplication {
    
        public static void main(String[] args) {
            try {
                SpringApplication.run(SwappingApiApplication.class, args);
                System.out.println("SwappingApiApplication 启动成功......");
            } catch (Exception e) {
                log.error("SwappingApiApplication 启动失败", e);
            }
        }
    }

    3.yml配置文件

    yml配置文件如下,双数据源如下,多数据源就往下加配置就行
    注意:相比较单数据源,应该用jdbc-url做key,否则会有运行时异常 多数据源java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
    ${my_first_mysql.host} 或 ${my_sencond_tidb.host} 可以是配置文件取的配置,也可以像username一样直接写死,都可以
    # 驱动配置信息
    spring:
      datasource:
        my-first-mysql:
          #连接池的配置信息
          driver-class-name: com.mysql.cj.jdbc.Driver
          type: com.alibaba.druid.pool.DruidDataSource
          druid:
            filters:
            max-active: 16
            initial-size: 2
            max-wait: 3000
            minIdle: 2
            time-between-eviction-runsMillis: 60000
            min-evictable-idle-timeMillis: 300000
            validation-query: SELECT 1
            test-while-idle: true
            test-on-borrow: false
            test-on-return: false
            pool-prepared-statements: false
            max-open-prepared-statements: -1
          jdbc-url: jdbc:mysql://${my_first_mysql.host}:${my_first_mysql.port}/my_first_mysql_dbName?characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=GMT%2B8&connectTimeout=2000&socketTimeout=150000
          username: XXX
          password: XXX
        my-sencond-tidb:
          #连接池的配置信息
          driver-class-name: com.mysql.cj.jdbc.Driver
          type: com.alibaba.druid.pool.DruidDataSource
          druid:
            filters:
            max-active: 16
            initial-size: 2
            max-wait: 3000
            minIdle: 2
            time-between-eviction-runsMillis: 60000
            min-evictable-idle-timeMillis: 300000
            validation-query: SELECT 1
            test-while-idle: true
            test-on-borrow: false
            test-on-return: false
            pool-prepared-statements: false
            max-open-prepared-statements: -1
          jdbc-url: jdbc:mysql://${my_sencond_tidb.host}:${my_sencond_tidb.port}/my_sencond_mysql_dbName?characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=GMT%2B8&connectTimeout=2000&socketTimeout=150000
          username: XXX
          password: XXX

    4.自定义DataSourceConfig

    自定义DataSourceConfig,而不用Springboot自启动的DataSourceConfig。
    两个数据源就定义两个,多个数据源就定义多个
    如果重点2没有区分各数据源的包扫描路径,会有运行时异常:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    import javax.sql.DataSource;
    
    
    /**
     * 第一个数据源
     *
     * @author xudong.shen
     * @date 2022/04/16
     */
    @Configuration
    @MapperScan(basePackages = "com.swapping.dao.mapper.mysql", sqlSessionTemplateRef  = "sqlSessionTemplate")//重点1 指定包扫描,当前这个数据源对应的mapper.java文件放在哪个包下,这里路径就指定哪里
    public class MyFirstDataSourceConfig {
    
        @Bean
        @Primary
        @ConfigurationProperties(prefix = "spring.datasource.my-first-mysql")//重点3 这里对应yml的当前数据源的前缀
        public DataSource dataSource() {
            return DataSourceBuilder.create().build();
    
        }
    
        @Bean
        @Primary
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/mysql/*.xml"));//重点2 指定包扫描,当前这个数据源对应的mapper.xml文件在哪个resource下的包里,这里路径就指定哪里
            // bean.setPlugins(new Interceptor[] {xxx}); // 设置MyBatis插件
            return bean.getObject();
        }
    
    
        @Bean
        @Primary
        public DataSourceTransactionManager testTransactionManager(DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        @Bean
        @Primary
        public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    import javax.sql.DataSource;
    
    /**
     * 第二个数据源
     *
     * @author xudong.shen
     * @date 2022/04/18
     */
    @Configuration
    @MapperScan(basePackages = "com.swapping.dao.mapper.tidb", sqlSessionTemplateRef  = "sqlSessionTemplateSecond")//重点1 指定包扫描,当前这个数据源对应的mapper.java文件放在哪个包下,这里路径就指定哪里
    public class MySecondDataSourceConfig {
    
    
       
        @Bean(name = "dataSourceSecond")
        @ConfigurationProperties(prefix = "spring.datasource.my-sencond-tidb")//重点3 这里对应yml的当前数据源的前缀
        public DataSource testDataSource() {
            return DataSourceBuilder.create().build();
    
        }
    
        @Bean(name = "sqlSessionFactorySecond")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("dataSourceSecond") DataSource dataSource) throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/tidb/*.xml"));//重点2 指定包扫描,当前这个数据源对应的mapper.xml文件在哪个resource下的包里,这里路径就指定哪里
            // bean.setPlugins(new Interceptor[] {xxx}); // 设置mybatis插件
            return bean.getObject();
        }
    
        @Bean(name = "transactionManagerSecond")
        public DataSourceTransactionManager testTransactionManager(@Qualifier("dataSourceSecond") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        @Bean(name = "sqlSessionTemplateSecond")
        public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("sqlSessionFactorySecond") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    }

    5.Mapper.java 和 Mapper.xml的说明

    到这里,多数据源的配置层面东西,就全部完成了。
    后面的mapper.java  mapper.xml  就放在上面各自数据源的指定包路径下,即可。
    后面Service调用Mapper的动作,就和单数据源 一样了。正常调用就行了。(当然,跨数据源了,事务肯定就行不通了!)
  • 相关阅读:
    11-15SQLserver基础--数据库之范式理论
    11-13SQLserver基础--数据库之事务
    11-11SQLserver基础--数据库之触发器
    C#中abstract和virtual区别
    virtual修饰符
    override 修饰符
    访问public
    访问修饰符protected
    访问修饰符private
    访问修饰符internal
  • 原文地址:https://www.cnblogs.com/sxdcgaq8080/p/16165778.html
Copyright © 2020-2023  润新知