1. 程式人生 > 實用技巧 >Spring Boot之JdbcTemplate多資料來源配置與使用

Spring Boot之JdbcTemplate多資料來源配置與使用

多資料來源配置

建立一個Spring配置類,定義兩個DataSource用來讀取application.properties中的不同配置。如下例子中,主資料來源配置為spring.datasource.primary開頭的配置,第二資料來源配置為spring.datasource.secondary開頭的配置。

之前在介紹使用JdbcTemplate和Spring-data-jpa時,都使用了單資料來源。在單資料來源的情況下,Spring Boot的配置非常簡單,只需要在application.properties檔案中配置連線引數即可。但是往往隨著業務量發展,我們通常會進行資料庫拆分或是引入其他資料庫,從而我們需要配置多個數據源,下面基於之前的JdbcTemplate和Spring-data-jpa例子分別介紹兩種多資料來源的配置方式。

多資料來源配置

建立一個Spring配置類,定義兩個DataSource用來讀取application.properties中的不同配置。如下例子中,主資料來源配置為spring.datasource.primary開頭的配置,第二資料來源配置為spring.datasource.secondary開頭的配置。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 packagecom.wls.diypro.util.datasource;
importorg.springframework.beans.factory.annotation.Qualifier; importorg.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; importorg.springframework.boot.context.properties.ConfigurationProperties; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.Primary; importorg.springframework.jdbc.core.JdbcTemplate; importjavax.sql.DataSource; @Configuration publicclassDataSourceConfig { @Bean(name ="primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix="spring.datasource.primary") publicDataSource primaryDataSource() { returnDataSourceBuilder.create().build(); } @Bean(name ="secondaryDataSource") @Qualifier("secondaryDataSource") @Primary @ConfigurationProperties(prefix="spring.datasource.secondary") publicDataSource secondaryDataSource() { returnDataSourceBuilder.create().build(); } @Bean(name ="primaryJdbcTemplate") publicJdbcTemplate primaryJdbcTemplate( @Qualifier("primaryDataSource") DataSource dataSource) { returnnewJdbcTemplate(dataSource); } @Bean(name ="secondaryJdbcTemplate") publicJdbcTemplate secondaryJdbcTemplate( @Qualifier("secondaryDataSource") DataSource dataSource) { returnnewJdbcTemplate(dataSource); } }

  

  

JdbcTemplate支援對應的application-dev.yml配置如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 spring: datasource: primary: driver-class-name: com.mysql.jdbc.Driver # url: jdbc:mysql://192.168.159.128:3306/mydb url: jdbc:mysql://192.168.11.131:3306/mydb username: wls password: Wls141215! secondary: driver-class-name: com.mysql.jdbc.Driver # url: jdbc:mysql://192.168.159.128:3306/mydb url: jdbc:mysql://192.168.11.131:3306/shopmall username: wls password: Wls141215!

對JdbcTemplate的支援比較簡單,只需要為其注入對應的datasource即可,如下例子,在建立JdbcTemplate的時候分別注入名為primaryDataSourcesecondaryDataSource的資料來源來區分不同的JdbcTemplate。

1 2 3 4 5 6 7 @Autowired @Qualifier("primaryJdbcTemplate") protectedJdbcTemplate primaryJdbcTemplate; @Autowired @Qualifier("secondaryJdbcTemplate") protectedJdbcTemplate secondaryJdbcTemplate;

  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 packagecom.wls.diypro.test.jdbcTemplateTest; importcom.wls.diypro.model.OrderInfo; importcom.wls.diypro.service.IOrderInfoService; importjunit.framework.Assert; importorg.junit.Before; importorg.junit.Test; importorg.junit.runner.RunWith; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.beans.factory.annotation.Qualifier; importorg.springframework.boot.test.context.SpringBootTest; importorg.springframework.jdbc.core.JdbcTemplate; importorg.springframework.test.context.junit4.SpringJUnit4ClassRunner; importjava.util.Date; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest publicclassJdbcTemplateTest { @Autowired @Qualifier("primaryJdbcTemplate") protectedJdbcTemplate primaryJdbcTemplate; @Autowired @Qualifier("secondaryJdbcTemplate") protectedJdbcTemplate secondaryJdbcTemplate; @Autowired privateIOrderInfoService iOrderInfoService; @Test publicvoidaddOrder()throwsException { OrderInfo orderInfo =newOrderInfo(); orderInfo.setAddressDetail("廣平大街"); orderInfo.setArea("大興區"); orderInfo.setCity("北京市"); orderInfo.setOrderNumber("10000001"); orderInfo.setOrderStatus("2"); orderInfo.setOrderTime(newDate()); orderInfo.setProvince("北京"); orderInfo.setReceiver("王老師"); orderInfo.setStreet("ces"); iOrderInfoService.addOrder(orderInfo); } @Before publicvoidsetUp() { primaryJdbcTemplate.update("DELETE FROM order_info "); secondaryJdbcTemplate.update("DELETE FROM order_info "); } @Test publicvoidtest()throwsException { // 往第一個資料來源中插入兩條資料 primaryJdbcTemplate.update("insert into order_info(order_flag,order_number,order_status,street) values(?, ?, ?, ?)","test","10001","S01","廣平大街"); primaryJdbcTemplate.update("insert into order_info(order_flag,order_number,order_status,street) values(?, ?, ?, ?)","test","10001","S01","廣平大街"); // 往第二個資料來源中插入一條資料,若插入的是第一個資料來源,則會主鍵衝突報錯 secondaryJdbcTemplate.update("insert into order_info(order_flag,order_number,order_status,street) values(?, ?, ?, ?)","test","10003","S02","廣平大街"); // 查一下第一個資料來源中是否有兩條資料,驗證插入是否成功 Assert.assertEquals("2", primaryJdbcTemplate.queryForObject("select count(1) from order_info", String.class)); // 查一下第一個資料來源中是否有兩條資料,驗證插入是否成功 Assert.assertEquals("1", secondaryJdbcTemplate.queryForObject("select count(1) from order_info", String.class)); } }