這裏以配置兩個mysql數據庫爲展現用例。持久層使用mybatis實現。兩個鏈接分別使用不一樣的鏈接池 druid 和 hikarijava
這裏介紹了一些相關的知識點,清楚後能夠跳過mysql
在pom依賴上它們是兩個不一樣的依賴文件。web
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
mybatis-spring-boot-starter相似一箇中間件,連接Springboot和mybatis,構建基於Springboot的mybatis應用程序。同時mybatis-spring-boot-starter做爲一個集成包是包含mybatis的。spring
mybatis-spring-boot-starter做爲一個集成包,若是在項目裏引入了該依賴那就不須要在顯示的依賴spring-boot-starter-jdbc,由於mybatis-spring-boot-starter是包含spring-boot-starter-jdbc的。sql
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright 2015-2018 the original author or authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot</artifactId> <version>1.3.2</version> </parent> <artifactId>mybatis-spring-boot-starter</artifactId> <name>mybatis-spring-boot-starter</name> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-autoconfigure</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> </dependencies> </project>
做爲一個集成包,能夠看到包含了mybatis、mybatis-spring、spring-boot-starter-jdbc。數據庫
/** * 獲得數據源 * 定義一個名字爲barDataSource的數據源 * * @return */ @Bean("barDataSource") public DataSource barDataSource() { DataSourceProperties dataSourceProperties = barDataSourceProperties(); log.info("bar datasource url:{}", dataSourceProperties.getUrl()); log.info("{}", dataSourceProperties.getType().getName()); return dataSourceProperties.initializeDataSourceBuilder().build(); } /** * 定義一個名字爲 barSqlSessionFactory 的SqlSession工廠,實現的時候使用名字爲barDataSource的數據源去實現 * @param dataSource * @return * @throws Exception */ @Bean("barSqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("barDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION)); return bean.getObject(); }
@Qualifier
指定使用名字爲barDataSource
數據源對象@ConfigurationProperties和@PropertySource都是用來讀取Spring的配置文件的,有三種配置方式express
package com.lucky.spring.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * Created by zhangdd on 2020/7/16 */ @PropertySource(value = "book.properties",encoding = "utf-8") @ConfigurationProperties(prefix = "book") @Component public class BookConfig { private String name; private String price; private String version; public String getName() { return name; } public String getPrice() { return price; } public String getVersion() { return version; } public void setName(String name) { this.name = name; } public void setPrice(String price) { this.price = price; } public void setVersion(String version) { this.version = version; } }
測試用例apache
@RestController public class BookController { @Autowired BookConfig bookConfig; @GetMapping("/api/queryBook") public String queryBook() { StringBuilder builder = new StringBuilder(); StringBuilder bookInfo = builder.append(bookConfig.getName()) .append(",") .append(bookConfig.getPrice()) .append(",") .append(bookConfig.getVersion()); return bookInfo.toString(); } }
person.name=張三 person.age=18 package com.lucky.spring.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * Created by zhangdd on 2020/7/16 */ @Component @PropertySource(value = "classpath:config/person.properties",encoding = "utf-8") @ConfigurationProperties(prefix = "person") public class PersonConfig { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } }
測試用例api
public class PersonController { @Autowired PersonConfig personConfig; @GetMapping("/api/queryPersonInfo") public String queryPersonInfo() { StringBuilder builder = new StringBuilder(); builder.append(personConfig.getName()) .append(",") .append(personConfig.getAge()); return builder.toString(); } }
car: price: 12345678 name: 奧迪 package com.lucky.spring.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * Created by zhangdd on 2020/7/16 */ @Component @ConfigurationProperties(prefix = "car") public class CarConfig { private String price; private String name; public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
測試用例session
package com.lucky.spring.controller; import com.lucky.spring.config.CarConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by zhangdd on 2020/7/16 */ @RestController public class CarController { @Autowired CarConfig carConfig; @GetMapping("/api/queryCarInfo") public String queryCarInfo() { StringBuilder builder = new StringBuilder(); builder.append(carConfig.getName()) .append(",") .append(carConfig.getPrice()); return builder.toString(); } }
基於環境背景信息,mysql數據庫,mybatis持久層,三方數據源druid。添加配置信息以下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.lucky</groupId> <artifactId>04spring-multi-datasource</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <java.version>1.8</java.version> </properties> <dependencies> <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-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.17</version> <scope>runtime</scope> </dependency> </dependencies> <configuration> <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build> </project>
既然是多數據源的配置操做,那就是配置數據源信息了。配置方式有兩種:
這裏以配置文件中爲例說明。
datasource: foo: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/readinglist?characterEncoding=utf8&useSSL=false username: root password: 12345678 bar: type: com.zaxxer.hikari.HikariDataSource url: jdbc:mysql://localhost:3306/shiro?characterEncoding=utf8&useSSL=false username: root password: 12345678
已經對信息進行了配置,下面就是對配置信息的使用了。
package com.lucky.spring.config; import lombok.extern.slf4j.Slf4j; 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.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; 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; /** * Created by zhangdd on 2020/7/13 */ @Configuration @Slf4j @MapperScan(basePackages = "com.lucky.spring.dao.foo", sqlSessionFactoryRef = "fooSqlSessionFactory") public class FooDataSourceConfig { static final String MAPPER_LOCATION = "classpath:mapper/foo/*.xml"; //=========foo 數據源相關配置 start================================================== @Bean @Primary// 該註解是指當有多個相同的bean時,優先使用用@Primary註解的bean @ConfigurationProperties("datasource.foo") public DataSourceProperties fooDataSourceProperties() { return new DataSourceProperties(); } /** * 返回 foo 對應的數據源 * * @return */ @Bean("fooDataSource") @Primary public DataSource fooDataSource() { DataSourceProperties dataSourceProperties = fooDataSourceProperties(); log.info("foo datasource url:{}", dataSourceProperties.getUrl()); log.info("{}", dataSourceProperties.getType().getName()); return dataSourceProperties.initializeDataSourceBuilder().build(); } /** * 返回foo 對應數據庫的會話工廠 * * @param ds * @return */ @Bean(name = "fooSqlSessionFactory") @Primary public SqlSessionFactory sqlSessionFactory(@Qualifier("fooDataSource") DataSource ds) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION)); return bean.getObject(); } /** * foo 對應的數據庫會話模版 * * @param sessionFactory * @return */ @Bean("fooSqlSessionTemplate") @Primary public SqlSessionTemplate sqlSessionTemplate(@Qualifier("fooSqlSessionFactory") SqlSessionFactory sessionFactory) { log.info("sessionFactory:{}", sessionFactory.toString()); return new SqlSessionTemplate(sessionFactory); } /** * 返回 foo 對應的數據庫事務 * * @param fooDatasource * @return */ @Bean @Primary public DataSourceTransactionManager fooTxManager(@Qualifier("fooDataSource") DataSource fooDatasource) { return new DataSourceTransactionManager(fooDatasource); } //=========foo 數據源相關配置 end================================================== }
@ConfigurationProperties("datasource.foo")
來裝載yml文件例的配置信息DataSource
,這裏調用第一步獲取配置信息。若是不在yml文件例進行配置,也能夠所有在這裏使用Java代碼實現建議將須要的都建立好,這樣方便作一些優化,好比超時時間、最大鏈接數、事務的處理方式
bar數據源的配置和foo的模式是同樣的,代碼以下:
package com.lucky.spring.config; import lombok.extern.slf4j.Slf4j; 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.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; 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.annotation.Resource; import javax.sql.DataSource; /** * Created by zhangdd on 2020/7/13 */ @Configuration @Slf4j @MapperScan(basePackages = "com.lucky.spring.dao.bar", sqlSessionFactoryRef = "barSqlSessionFactory") public class BarDataSourceConfig { static final String MAPPER_LOCATION = "classpath:mapper/bar/*.xml"; //=========bar 數據源相關配置 start================================================== @Bean @ConfigurationProperties("datasource.bar") public DataSourceProperties barDataSourceProperties() { return new DataSourceProperties(); } /** * 獲得數據源 * * @return */ @Bean("barDataSource") public DataSource barDataSource() { DataSourceProperties dataSourceProperties = barDataSourceProperties(); log.info("bar datasource url:{}", dataSourceProperties.getUrl()); log.info("{}", dataSourceProperties.getType().getName()); return dataSourceProperties.initializeDataSourceBuilder().build(); } /** * * @param dataSource * @return * @throws Exception */ @Bean("barSqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("barDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION)); return bean.getObject(); } /** * bar 對應的數據庫會話模版 * * @param sessionFactory * @return */ @Bean("barSqlSessionTemplate") public SqlSessionTemplate sqlSessionTemplate(@Qualifier("barSqlSessionFactory") SqlSessionFactory sessionFactory) { return new SqlSessionTemplate(sessionFactory); } @Bean @Resource public DataSourceTransactionManager barTxManager(@Qualifier("barDataSource") DataSource barDatasource) { return new DataSourceTransactionManager(barDatasource); } //=========bar 數據源相關配置 end================================================== }
兩個數據源foo和bar鏈接的數據庫分別是readinglist和shiro,分別以readinglist數據庫例的foo表和tpermission表爲例。
@RestController public class MultiDataController { @Autowired TPermissionMapper permissionMapper; @Autowired FooMapper fooMapper; @GetMapping("/api/getData") public MultiDataVo getData() { List<TPermission> tPermissions = permissionMapper.queryList(); List<Foo> foos = fooMapper.queryList(); MultiDataVo dataVo = new MultiDataVo(); dataVo.setFoos(foos); dataVo.setPermissions(tPermissions); return dataVo; } }
package com.lucky.spring.vo; import com.lucky.spring.model.bar.TPermission; import com.lucky.spring.model.foo.Foo; import lombok.Data; import java.util.List; /** * Created by zhangdd on 2020/7/14 */ @Data public class MultiDataVo { private List<TPermission> permissions; private List<Foo> foos; }