这里以配置两个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; }