背景: 公司要新建一個數據項目,因為要查詢多個數據源的數據,且之前也沒有做項目搭建的筆記,這次做一個記錄。開箱即用,真香警告!
搭建過程中遇到了一些問題,會逐步說明。代碼地址:https://gitee.com/aaron_qc/multi-datasource.git
- 先上主菜。多數據源配置步驟
- 引入依賴 tkmapper + druid + mysql + spring-boot-configuration-processor
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>2.1.5.RELEASE</version> </dependency> <!-- mysql and mybatis etc --> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency> <!-- druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
-
- 配置如下
- 啟動類加上@EnableConfigurationProperties。
- OceanApplication
/** * @author QuCheng on 2019-09-16. * EnableConfigurationProperties 使 @ConfigurationProperties 注解的類(需要加@Component)生效。 */ @EnableConfigurationProperties @SpringBootApplication public class OceanApplication { public static void main(String[] args) { SpringApplication.run(OceanApplication.class, args); } }
- OceanApplication
- yml配置相應屬性
- application.yml 屬性自定義名稱,只需要和對應java類對應即可
druid: # 數據源配置 user: root password: xxxx driverClass: com.mysql.cj.jdbc.Driver # 初始化 最小 最大 initialSize: 5 minIdle: 5 maxActive: 20 testOnBorrow: false urlIceberg: jdbc:mysql://106.12.176.120/iceberg?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false # 設置時區 urlOcean: jdbc:mysql://106.12.176.120/ocean?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false # 設置時區 urlAccount: jdbc:mysql://106.12.176.120/account?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useSSL=false # 設置時區
- application.yml 屬性自定義名稱,只需要和對應java類對應即可
- 自定義屬性加載父類BaseProperty
- 映射yml配置 。
package com.hb.ocean.druid; import com.alibaba.druid.pool.DruidDataSource; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import javax.sql.DataSource; /** * datasource base class * @author qucheng */ @Data @ConfigurationProperties(prefix = "druid") @Component class BaseProperty { protected String user; protected String password; protected String driverClass; protected int initialSize; protected int maxActive; protected int minIdle; protected boolean testOnBorrow; protected String urlAccount; protected String urlOcean; protected String urlIceberg; DataSource createDataSource(String url) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driverClass); dataSource.setUrl(url); dataSource.setUsername(user); dataSource.setPassword(password); dataSource.setInitialSize(initialSize); dataSource.setMaxActive(maxActive); dataSource.setMinIdle(minIdle); dataSource.setTestOnBorrow(testOnBorrow); return dataSource; } }
- 映射yml配置 。
- 各數據源配置自己的映射路徑(mapper接口+xml文件)
- 配置路徑 -- 此處省略2個其他配置
package com.hb.ocean.druid; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.stereotype.Component; import tk.mybatis.spring.annotation.MapperScan; import javax.sql.DataSource; /** * account datasource * MapperScan(如果要使用表名映射實體使用tk)注解用於綁定掃描的包和指定的數據源,且指定目錄下的mapper無需加注解處理 * * @author qucheng */ @Component @MapperScan(basePackages = "com.hb.ocean.mapper.account", sqlSessionFactoryRef = "accountSqlSessionFactory") public class AccountConfig extends BaseProperty { @Bean(name = "accountDataSource") public DataSource createDataSource() { return createDataSource(urlAccount); } @Bean(name = "accountTransactionManager") public DataSourceTransactionManager accountTransactionManager() { return new DataSourceTransactionManager(createDataSource()); } @Bean(name = "accountSqlSessionFactory") public SqlSessionFactory masterSqlSessionFactory(@Qualifier("accountDataSource") DataSource accountDataSource) throws Exception { final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(accountDataSource); String mapperLocation = "classpath:mapper/account/*.xml"; sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(mapperLocation)); return sessionFactory.getObject(); } }
- 配置路徑 -- 此處省略2個其他配置
- 創建相應目錄下的文件。在啟動項目時會加載。
- 結構如圖
- 結構如圖
- 啟動類加上@EnableConfigurationProperties。
- 成功之后啟動測試結果如下
- 測試代碼
package com.hb.ocean.controller; import com.hb.ocean.mapper.account.UserMapper; import com.hb.ocean.mapper.iceberg.ItemOrderMapper; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; /** * @author QuCheng on 2019-09-17. */ @RestController @RequestMapping("/qc") public class TestView { /** * 不推薦直接在controller層引入Dao層。這里只做演示使用 */ @Resource private UserMapper userMapper; @Resource private ItemOrderMapper itemOrderMapper; @GetMapping("/test") public String test() { System.out.println("用戶數:" + userMapper.selectCountUser(null, null)); System.out.println("訂單數:" + itemOrderMapper.selectCountSuccessOrder(null, null)); return "ok"; } }
- 測試結果
- 測試代碼
- 引入依賴 tkmapper + druid + mysql + spring-boot-configuration-processor
以上過程也出現的幾個問題
- 多數據源共用了一個yml基礎配置,除了數據源url地址不一致之外。
- 自定義yml屬性配置項需要
- 引入spring-boot-configuration-processor。
- 啟動類使用注解@EnableConfigurationProperties
- 解析類上面要引入3個注解@Data只是為了方便。@ConfigurationProperties(prefix = "druid")指明讀取的是"druid"開始的屬性。@Component表示由容器管理
- 配置類@MapperScan注解是使用的tk.mybatis.spring.annotation.MapperScan注解。org.mybatis.spring.annotation.MapperScan也可以用但是它不能配合使用@Table注解映射表。
springboot多數據源配置的過程如上。這是demo版本,之后會出更多記錄文章。實際應用數據中還涉及
- eureka的注冊發現。啟動類注解引入
- feign接口調用以及失敗熔斷
- 優雅停機簡單處理
- swagger文檔
- redis分布式事務