• springboot多个数据源


    1、启动两个mysql,可以按照如下操作使用docker来部署mysql容器,比较简单

    https://www.cnblogs.com/qq931399960/p/11527222.html

    2、如果配置了多个数据源,则默认的数据源配置就不再生效了,如果配置两个数据源,则两个数据都需要自定义,找到javax.sql.DataSource接口,F4查看其实现类

    单数据源使用自动配置时的配置

    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://192.168.101.116:3306/myapp001?useSSL=false
    spring.datasource.username=root
    spring.datasource.password=12345
    spring.datasource.hikari.maximum-pool-size=20

     3、我们使用的为HikariCP连接池,所以需要实例化HikariDataSource,进入到该类源码中,发现其继承了HikariConfig,进入HikariConfig,可以看到一些很熟悉的属性,不过当前测试时指挥使用到一些简单配置

    通过https://www.cnblogs.com/qq931399960/p/11523723.html了解到,springboot可以通过@ConfigurationProperties注解批量的把参数注入到实体类中,所以我们就可以定义自己的数据源了

    多个数据源配置及测试

    为了方便测试,注入数据源后,使用JdbcTemplate来操作数据库

    端口3306的myapp001数据库中,user表存在三条数据

    mysql> use myapp001;
    Database changed
    mysql> select * from user;
    +------+------+
    | id   | name |
    +------+------+
    |    1 | aa   |
    |    2 | bb   |
    |    3 | cc   |
    +------+------+
    3 rows in set (0.04 sec)

    端口3307的myapp002数据库中,uer表数据为空

    mysql> use myapp002;
    Database changed
    mysql> select * from user;
    Empty set (0.02 sec)

    1、配置数据源

    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.jdbc-url=jdbc:mysql://192.168.101.116:3306/myapp001?useSSL=false
    spring.datasource.username=root
    spring.datasource.password=12345
    spring.datasource.maximum-pool-size=30
    
    spring.datasource.app.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.app.jdbc-url=jdbc:mysql://192.168.101.116:3307/myapp002?useSSL=false
    spring.datasource.app.username=root
    spring.datasource.app.password=12345
    spring.datasource.app.maximum-pool-size=20

    2、注入数据源和JdbcTemplate

    package com.demo.bootdemo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import com.zaxxer.hikari.HikariDataSource;
    
    @SpringBootApplication
    public class MultidatasourceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MultidatasourceApplication.class, args);
        }
    
        @Bean("datasource")
        @ConfigurationProperties("spring.datasource")
        public HikariDataSource datasource() {
            return new HikariDataSource();
        }
    
        @Bean("jdbcTemplate")
        public JdbcTemplate jdbcTemplate() {
            return new JdbcTemplate(datasource());
        }
    
        @Bean("datasourceapp")
        @ConfigurationProperties("spring.datasource.app")
        public HikariDataSource datasourceapp() {
            return new HikariDataSource();
        }
    
        @Bean("jdbcTemplateApp")
        public JdbcTemplate jdbcTemplateApp() {
            return new JdbcTemplate(datasourceapp());
        }
    
    }

    3、测试输出

    package com.demo.bootdemo;
    
    import java.util.List;
    import java.util.Map;
    
    import javax.annotation.Resource;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MainBusi implements CommandLineRunner {
    
        private Logger logger = LoggerFactory.getLogger(MainBusi.class);
    
        @Resource
        private JdbcTemplate jdbcTemplate;
    
        @Resource
        private JdbcTemplate jdbcTemplateApp;
    
        @Override
        public void run(String... args) throws Exception {
    
            List<Map<String, Object>> queryForList = jdbcTemplate.queryForList("select * from user");
            logger.info(queryForList.toString());
    
            List<Map<String, Object>> queryForList2 = jdbcTemplateApp.queryForList("select * from user");
            logger.info(queryForList2.toString());
    
        }
    
    }

    启动程序,查看输出结果,截取其中关键部分如下,可以看到,两个数据源的配置都是正确的,如果还需要其他参数

    2019-09-16 16:01:45.359  INFO 67868 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
    2019-09-16 16:01:45.556  INFO 67868 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
    2019-09-16 16:01:45.689  INFO 67868 --- [           main] com.demo.bootdemo.MainBusi               : [{id=1, name=aa}, {id=2, name=bb}, {id=3, name=cc}]
    2019-09-16 16:01:45.690  INFO 67868 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Starting...
    2019-09-16 16:01:45.749  INFO 67868 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Start completed.
    2019-09-16 16:01:45.757  INFO 67868 --- [           main] com.demo.bootdemo.MainBusi               : []

    测试两个数据源,其中一个使用默认自动配置

    其实主要区别为url,自定义的HikariDataSource需要使用jdbc-url,而默认的为url,将3306端口的jdbc-url改为url

    spring.datasource.url=jdbc:mysql://192.168.101.116:3306/myapp001?useSSL=false

    注释或者删除对默认数据源及JdbcTemplate代码

    //    @Bean("datasource")
    //    @ConfigurationProperties("spring.datasource")
    //    public HikariDataSource datasource() {
    //        return new HikariDataSource();
    //    }
    //
    //    @Bean("jdbcTemplate")
    //    public JdbcTemplate jdbcTemplate() {
    //        return new JdbcTemplate(datasource());
    //    }

    启动程序,可以发现当前只有一个数据源,jdbcTemplate和jdbcTemplateApp使用到的数据源是相同的。都是使用的自定义的数据源。通过该例子可知,一旦自定义了数据源,则之前默认的数据源就不再生效

    2019-09-16 16:08:48.235  INFO 71488 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
    2019-09-16 16:08:48.660  INFO 71488 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
    2019-09-16 16:08:48.689  INFO 71488 --- [           main] com.demo.bootdemo.MainBusi               : []
    2019-09-16 16:08:48.692  INFO 71488 --- [           main] com.demo.bootdemo.MainBusi               : []
    2019-09-16 16:08:48.697  INFO 71488 --- [       Thread-2] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
    2019-09-16 16:08:48.707  INFO 71488 --- [       Thread-2] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

    springboot官网配置多个数据源

    两种方式

    一、使用DataSourceBuilder来创建

    参考如下章节第一部分

     这种方式如果使用的为HikarDataSource,则需要将配置中的url改为jdbc-url

    二、多个配置前缀来创建,基本配置与连接池配置分开(类似于springboot的自动配置)

    在springboot官网有上述一段描述,上述文字下面就是两个数据源配置的具体代码,并且看这意思,是说如果有两个数据源,必须将其中的一个设置为Primary,上述的方式没有用到springboot官方提供的的配置,不过也没发现问题,不过也可以添加上Primary注解,不影响结果.在这里也有一行描述

    If you create your own DataSource, the auto-configuration backs off,解释了上面“测试两个数据源,其中一个使用默认自动配置”的现象。

    下面就按照官网的解释,声明两个数据源,并使用JdbcTemplate测试

    1、配置

    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://192.168.101.116:3306/myapp001?useSSL=false
    spring.datasource.username=root
    spring.datasource.password=12345
    spring.datasource.pool.maximum-pool-size=30 ## 注意前缀,要与获取数据源时@ConfigurationProperties注解的一致,否则连接池配置不生效,下同
    
    spring.datasource.app.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.app.url=jdbc:mysql://192.168.101.116:3307/myapp002?useSSL=false
    spring.datasource.app.username=root
    spring.datasource.app.password=12345
    spring.datasource.app.pool.maximum-pool-size=20

    2、注入数据源和JdbcTemplate

    package com.demo.bootdemo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Primary;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    import com.zaxxer.hikari.HikariDataSource;
    
    @SpringBootApplication
    public class MultidatasourceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MultidatasourceApplication.class, args);
        }
    
        @Bean
        @Primary
        @ConfigurationProperties("spring.datasource")
        public DataSourceProperties datasourcepro() {
            return new DataSourceProperties();
        }
    
        @Bean
        @Primary
        @ConfigurationProperties("spring.datasource.pool")
        public HikariDataSource datasource() {
            return datasourcepro().initializeDataSourceBuilder().type(HikariDataSource.class).build();
        }
    
        @Bean("jdbcTemplate")
        @Primary
        public JdbcTemplate jdbcTemplate() {
            return new JdbcTemplate(datasource());
        }
    
        @Bean
        @ConfigurationProperties("spring.datasource.app")
        public DataSourceProperties datasourceproApp() {
            return new DataSourceProperties();
        }
    
        @Bean
        @ConfigurationProperties("spring.datasource.app.pool") // 该配置对应配置文件中连接池的配置信息,否则连接池配置不生效
        public HikariDataSource datasourceApp() {
            return datasourceproApp().initializeDataSourceBuilder().type(HikariDataSource.class).build();
        }
    
        @Bean("jdbcTemplateApp")
        public JdbcTemplate jdbcTemplateApp() {
            return new JdbcTemplate(datasourceApp());
        }
    
    }

    3、输出结果

    2019-09-16 16:28:14.351  INFO 70720 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
    2019-09-16 16:28:14.574  INFO 70720 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
    2019-09-16 16:28:14.601  INFO 70720 --- [           main] com.demo.bootdemo.MainBusi               : [{id=1, name=aa}, {id=2, name=bb}, {id=3, name=cc}]
    2019-09-16 16:28:14.601  INFO 70720 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Starting...
    2019-09-16 16:28:14.621  INFO 70720 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-2 - Start completed.
    2019-09-16 16:28:14.638  INFO 70720 --- [           main] com.demo.bootdemo.MainBusi               : []

    与我们期望的一致,而且这里面的配置和单机使用的时候是一致的,而且使用springboot官网的多个数据源配置,几乎所有的参数配置中映射到实体类中的key和单数据源都是一样的,不需要做特殊的改动。建议还是用springboot官方推荐的这种方式来实现多个数据源。

  • 相关阅读:
    能自证的任意类型即为动态类型
    类型系统:类型信息引用 isa
    类型系统:类型检查、类型转换、任意类型-强类型、类型转换
    动态类型与弱类型
    Swift Intermediate Language (SIL)
    swift -Dynamic Dispatch
    swift VTables
    Which dispatch method would be used in Swift?
    Which dispatch method would be used in Swift?-Existential Container
    Swift protocol extension method is called instead of method implemented in subclass
  • 原文地址:https://www.cnblogs.com/qq931399960/p/11525065.html
Copyright © 2020-2023  润新知