在上一篇文章《优雅整合 SpringBoot+Mybatis ,多是你见过最详细的一篇》中,带着你们整合了 SpringBoot 和 Mybatis ,咱们在当时使用的时单数据源的状况,这种状况下 Spring Boot的配置很是简单,只须要在 application.properties 文件中配置数据库的相关链接参数便可。可是每每随着业务量发展,咱们一般会进行数据库拆分或是引入其余数据库,从而咱们须要配置多个数据源。下面基于 SpringBoot+Mybatis ,带着你们看一下 SpringBoot 中如何配置多数据源。java
这篇文章所涉及的代码实际上是基于上一篇文章《优雅整合 SpringBoot+Mybatis ,多是你见过最详细的一篇》 的项目写的,可是为了考虑部分读者没有读过上一篇文章,因此我仍是会一步一步带你们走完每一步,力争新手也能在看完以后独立实践。mysql
目录:git
<!-- MarkdownTOC -->github
<!-- /MarkdownTOC -->sql
建立一个基本的 SpringBoot 项目,我这里就很少说这方面问题了,具体能够参考下面这篇文章:数据库
http://www.javashuo.com/article/p-qmwpdnah-bz.html安全
本项目结构:springboot
咱们一共建立的两个数据库,而后分别在这两个数据库中建立了 user 用户表、money工资详情表。
咱们的用户表很简单,只有 4 个字段:用户 id、姓名、年龄、余额。以下图所示:
添加了“余额money”字段是为了给你们简单的演示一下事务管理的方式。
咱们的工资详情表也很简单,也只有 4 个字段: id、基本工资、奖金和惩罚金。以下图所示:
建表语句:
用户表:
CREATE TABLE `user` ( `id` int(13) NOT NULL AUTO_INCREMENT COMMENT '主键', `name` varchar(33) DEFAULT NULL COMMENT '姓名', `age` int(3) DEFAULT NULL COMMENT '年龄', `money` double DEFAULT NULL COMMENT '帐户余额', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
工资详情表:
CREATE TABLE `money` ( `id` int(33) NOT NULL AUTO_INCREMENT COMMENT '主键', `basic` int(33) DEFAULT NULL COMMENT '基本工资', `reward` int(33) DEFAULT NULL COMMENT '奖金', `punishment` int(33) DEFAULT NULL COMMENT '惩罚金', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
因为要整合 springboot 和 mybatis 因此加入了artifactId 为 mybatis-spring-boot-starter 的依赖,因为使用了Mysql 数据库 因此加入了artifactId 为 mysql-connector-java 的依赖。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </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>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
配置两个数据源:数据库1和数据库2!
注意事项:
在1.0 配置数据源的过程当中主要是写成:spring.datasource.url 和spring.datasource.driverClassName。
而在2.0升级以后须要变动成:spring.datasource.jdbc-url和spring.datasource.driver-class-name!否则在链接数据库时可能会报下面的错误:
### Error querying database. Cause: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.
另外在在2.0.2+版本后须要在datasource后面加上hikari,若是你没有加的话,一样可能会报错。
server.port=8335 # 配置第一个数据源 spring.datasource.hikari.db1.jdbc-url=jdbc:mysql://127.0.0.1:3306/erp?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8 spring.datasource.hikari.db1.username=root spring.datasource.hikari.db1.password=153963 spring.datasource.hikari.db1.driver-class-name=com.mysql.cj.jdbc.Driver # 配置第二个数据源 spring.datasource.hikari.db2.jdbc-url=jdbc:mysql://127.0.0.1:3306/erp2?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8 spring.datasource.hikari.db2.username=root spring.datasource.hikari.db2.password=153963 spring.datasource.hikari.db2.driver-class-name=com.mysql.cj.jdbc.Driver
User.java
public class User { private int id; private String name; private int age; private double money; ... 此处省略getter、setter以及 toString方法 }
Money.java
public class Money { private int basic; private int reward; private int punishment; ... 此处省略getter、setter以及 toString方法 }
经过 Java 类来实现对两个数据源的配置,这一部分是最关键的部分了,这里主要提一下下面这几点:
@MapperScan
注解中咱们声明了使用数据库1的dao类所在的位置,还声明了 SqlSessionTemplate 。SqlSessionTemplate是MyBatis-Spring的核心。这个类负责管理MyBatis的SqlSession,调用MyBatis的SQL方法,翻译异常。SqlSessionTemplate是线程安全的,能够被多个DAO所共享使用。bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/db2/*.xml"));
@Qualifier("db1SqlSessionTemplate")
@Primary
注解来声明这个数据库时默认数据库,否则可能会报错。DataSource1Config.java
@Configuration @MapperScan(basePackages = "top.snailclimb.db1.dao", sqlSessionTemplateRef = "db1SqlSessionTemplate") public class DataSource1Config { /** * 生成数据源. @Primary 注解声明为默认数据源 */ @Bean(name = "db1DataSource") @ConfigurationProperties(prefix = "spring.datasource.hikari.db1") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); } /** * 建立 SqlSessionFactory */ @Bean(name = "db1SqlSessionFactory") @Primary public SqlSessionFactory testSqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); // bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/db1/*.xml")); return bean.getObject(); } /** * 配置事务管理 */ @Bean(name = "db1TransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "db1SqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
DataSource2Config.java
@Configuration @MapperScan(basePackages = "top.snailclimb.db2.dao", sqlSessionTemplateRef = "db2SqlSessionTemplate") public class DataSource2Config { @Bean(name = "db2DataSource") @ConfigurationProperties(prefix = "spring.datasource.hikari.db2") public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "db2SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); //bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/db2/*.xml")); return bean.getObject(); } @Bean(name = "db2TransactionManager") public DataSourceTransactionManager testTransactionManager(@Qualifier("db2DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "db2SqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
新建两个不一样的包存放两个不一样数据库的 dao 和 service。
对于两个数据库,咱们只是简单的测试一个查询这个操做。在上一篇文章《优雅整合 SpringBoot+Mybatis ,多是你见过最详细的一篇》中,我带着你们使用注解实现了数据库基本的增删改查操做。
UserDao.java
@Qualifier("db1SqlSessionTemplate") public interface UserDao { /** * 经过名字查询用户信息 */ @Select("SELECT * FROM user WHERE name = #{name}") User findUserByName(String name); }
MoneyDao.java
@Qualifier("db2SqlSessionTemplate") public interface MoneyDao { /** * 经过id 查看工资详情 */ @Select("SELECT * FROM money WHERE id = #{id}") Money findMoneyById(@Param("id") int id); }
Service 层很简单,没有复杂的业务逻辑。
UserService.java
@Service public class UserService { @Autowired private UserDao userDao; /** * 根据名字查找用户 */ public User selectUserByName(String name) { return userDao.findUserByName(name); } }
MoneyService.java
@Service public class MoneyService { @Autowired private MoneyDao moneyDao; /** * 根据名字查找用户 */ public Money selectMoneyById(int id) { return moneyDao.findMoneyById(id); } }
Controller 层也很是简单。
UserController.java
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping("/query") public User testQuery() { return userService.selectUserByName("Daisy"); } }
MoneyController.java
@RestController @RequestMapping("/money") public class MoneyController { @Autowired private MoneyService moneyService; @RequestMapping("/query") public Money testQuery() { return moneyService.selectMoneyById(1); } }
//此注解表示SpringBoot启动类 @SpringBootApplication public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); } }
这样基于SpirngBoot2.0+ 的 SpringBoot+Mybatis 多数据源配置就已经完成了, 两个数据库均可以被访问了。