在上一篇文章《優雅整合 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 多數據源配置就已經完成了, 兩個數據庫均可以被訪問了。