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官方推薦的這種方式來實現多個數據源。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM