springboot-multisource

項目中常常會出現須要同時鏈接兩個數據源的狀況,這裏基於MyBatis來配置兩個數據源,並演示如何切換不一樣的數據源。java

經過自定義註解+AOP的方式,來簡化這種數據源的切換操做。mysql

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <druid.version>1.1.2</druid.version>
    <mysql-connector.version>8.0.7-dmr</mysql-connector.version>
    <mybatis-plus.version>2.1.8</mybatis-plus.version>
    <mybatisplus-spring-boot-starter.version>1.0.5</mybatisplus-spring-boot-starter.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql-connector.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>${druid.version}</version>
    </dependency>
    <!-- MyBatis plus加強和springboot的集成-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus</artifactId>
        <version>${mybatis-plus.version}</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatisplus-spring-boot-starter</artifactId>
        <version>${mybatisplus-spring-boot-starter.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-all</artifactId>
        <version>1.3</version>
        <scope>test</scope>
    </dependency>
</dependencies>

初始化數據庫

這裏咱們須要建立兩個數據庫,初始化腳本以下:spring

-- -------------------------------------如下是pos業務庫開始------------------------------------------- CREATE DATABASE IF NOT EXISTS pos default charset utf8 COLLATE utf8_general_ci; SET FOREIGN_KEY_CHECKS=0; USE pos; -- 後臺管理用戶表 DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `id` INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵ID', `username` VARCHAR(32) NOT NULL COMMENT '帳號', `name` VARCHAR(16) DEFAULT '' COMMENT '名字', `password` VARCHAR(128) DEFAULT '' COMMENT '密碼', `salt` VARCHAR(64) DEFAULT '' COMMENT 'md5密碼鹽', `phone` VARCHAR(32) DEFAULT '' COMMENT '聯繫電話', `tips` VARCHAR(255) COMMENT '備註', `state` TINYINT(1) DEFAULT 1 COMMENT '狀態 1:正常 2:禁用', `created_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `updated_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間' ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='後臺管理用戶表'; -- 下面是pos數據庫中的插入數據 INSERT INTO `t_user` VALUES (1,'admin','系統管理員','123456','www', '17890908889', '系統管理員', 1, '2017-12-12 09:46:12', '2017-12-12 09:46:12'); INSERT INTO `t_user` VALUES (2,'aix','張三','123456','eee', '17859569358', '', 1, '2017-12-12 09:46:12', '2017-12-12 09:46:12'); -- -------------------------------------如下biz業務庫開始------------------------------------------- CREATE DATABASE IF NOT EXISTS biz default charset utf8 COLLATE utf8_general_ci; SET FOREIGN_KEY_CHECKS=0; USE biz; -- 後臺管理用戶表 DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `id` INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵ID', `username` VARCHAR(32) NOT NULL COMMENT '帳號', `name` VARCHAR(16) DEFAULT '' COMMENT '名字', `password` VARCHAR(128) DEFAULT '' COMMENT '密碼', `salt` VARCHAR(64) DEFAULT '' COMMENT 'md5密碼鹽', `phone` VARCHAR(32) DEFAULT '' COMMENT '聯繫電話', `tips` VARCHAR(255) COMMENT '備註', `state` TINYINT(1) DEFAULT 1 COMMENT '狀態 1:正常 2:禁用', `created_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `updated_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間' ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='後臺管理用戶表'; -- 下面是biz數據庫中的插入數據 INSERT INTO `t_user` VALUES (1,'admin1','系統管理員','123456','www', '17890908889', '系統管理員', 1, '2017-12-12 09:46:12', '2017-12-12 09:46:12'); INSERT INTO `t_user` VALUES (2,'aix1','張三','123456','eee', '17859569358', '', 1, '2017-12-12 09:46:12', '2017-12-12 09:46:12');

能夠看到我建立了兩個數據庫pos和biz,同時還初始化了用戶表,並分別插入兩條初始數據。注意用戶名數據不相同。sql

配置文件

接下來修改application.yml配置文件,以下:數據庫

################### 自定義配置 ################### xncoding: muti-datasource-open: true #是否開啓多數據源(true/false) ################### mybatis-plus配置 ################### mybatis-plus: mapper-locations: classpath*:com/xncoding/pos/common/dao/repository/mapping/*.xml typeAliasesPackage: > com.xncoding.pos.common.dao.entity global-config: id-type: 0 # 0:數據庫ID自增 1:用戶輸入id 2:全局惟一id(IdWorker) 3:全局惟一ID(uuid) db-column-underline: false refresh-mapper: true configuration: map-underscore-to-camel-case: true cache-enabled: true #配置的緩存的全局開關 lazyLoadingEnabled: true #延時加載的開關 multipleResultSetsEnabled: true #開啓的話,延時加載一個屬性時會加載該對象所有屬性,不然按需加載屬性 #默認數據源 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/pos?useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8 username: root password: 123456 #多數據源 biz: datasource: url: jdbc:mysql://127.0.0.1:3306/biz?useSSL=false&autoReconnect=true&tinyInt1isBit=false&useUnicode=true&characterEncoding=utf8 username: root password: 123456

添加了一個自定義配置項muti-datasource-open,用來控制是否開啓多數據源支持。這個配置項後面會用到。 接下來定義MyBatis的配置,最後定義了兩個MySQL數據庫的鏈接信息,一個是pos庫,一個是biz庫。緩存

 

動態切換數據源

這裏經過Spring的AOP技術實現數據源的動態切換。springboot

多數據源的常量類:mybatis

public interface DSEnum { String DATA_SOURCE_CORE = "dataSourceCore";         //核心數據源
    String DATA_SOURCE_BIZ = "dataSourceBiz";            //其餘業務的數據源
}

datasource的上下文,用來存儲當前線程的數據源類型:app

 

 1 public class DataSourceContextHolder {  2 
 3     private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();  4 
 5     /**  6  * @param dataSourceType 數據庫類型  7  * @Description: 設置數據源類型  8      */
 9     public static void setDataSourceType(String dataSourceType) { 10         contextHolder.set(dataSourceType); 11  } 12 
13     /** 14  * @Description: 獲取數據源類型 15      */
16     public static String getDataSourceType() { 17         return contextHolder.get(); 18  } 19 
20     public static void clearDataSourceType() { 21  contextHolder.remove(); 22  } 23 }

 

定義動態數據源,繼承AbstractRoutingDataSource :ide

 

1 public class DynamicDataSource extends AbstractRoutingDataSource { 2 
3  @Override 4     protected Object determineCurrentLookupKey() { 5         return DataSourceContextHolder.getDataSourceType(); 6  } 7 }

 

接下來自定義一個註解,用來在Service方法上面註解使用哪一個數據源:

 

1 @Inherited 2 @Retention(RetentionPolicy.RUNTIME) 3 @Target(ElementType.METHOD) 4 public @interface DataSource { 5 
6     String name() default ""; 7 }

 

最後,最核心的AOP類定義:

 

 1 @Aspect  2 @Component  3 @ConditionalOnProperty(prefix = "code", name = "muti-datasource-open", havingValue = "true")  4 public class MultiSourceExAop implements Ordered {  5 
 6     private static final Logger LOGGER = LoggerFactory.getLogger(MultiSourceExAop.class);  7 
 8     @Pointcut(value = "@annotation(com.code.springbootmultisource.common.annotation.DataSource)")  9     private void cut() {} 10 
11     @Around("cut()") 12     public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { 13         Signature signature = proceedingJoinPoint.getSignature(); 14         MethodSignature methodSignature = null; 15         if (!(signature instanceof MethodSignature)) { 16             throw new IllegalArgumentException("該註解只能用於方法"); 17  } 18         methodSignature = (MethodSignature) signature; 19         Object target = proceedingJoinPoint.getTarget(); 20         Method currentMethod = target.getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes()); 21 
22         DataSource dataSource = currentMethod.getAnnotation(DataSource.class); 23         if (dataSource != null) { 24  DataSourceContextHolder.setDataSourceType(dataSource.name()); 25             LOGGER.info("數據源設置爲: " + dataSource.name()); 26         } else { 27  DataSourceContextHolder.setDataSourceType(DSEnum.DATA_SOURCE_CORE); 28             LOGGER.info("數據源設置爲: " + DSEnum.DATA_SOURCE_CORE); 29  } 30         try { 31             return proceedingJoinPoint.proceed(); 32         } finally { 33             LOGGER.debug("清空數據源信息!"); 34  DataSourceContextHolder.clearDataSourceType(); 35  } 36  } 37 
38     /** 39  * aop的順序要早於spring的事務 40      */
41  @Override 42     public int getOrder() { 43         return 1; 44  } 45 }

 

這裏使用到了註解@ConditionalOnProperty,只有當個人配置文件中muti-datasource-open=true的時候註解纔會生效。

另外還有一個要注意的地方,就是order,aop的順序必定要早於spring的事務,這裏我將它設置成1,後面你會看到我將spring事務順序設置成2。

配置類

首先有兩個屬性類:

  1. DruidProperties 鏈接池的屬性類
  2. MutiDataSourceProperties biz數據源的屬性類
 1 @Component  2 @ConfigurationProperties(prefix = "spring.datasource")  3 public class DruidProperties {  4 
 5     private String url;  6 
 7     private String username;  8 
 9     private String password;  10 
 11     private String driverClassName = "com.mysql.cj.jdbc.Driver";  12 
 13     private Integer initialSize = 10;  14 
 15     private Integer minIdle = 3;  16 
 17     private Integer maxActive = 60;  18 
 19     private Integer maxWait = 60000;  20 
 21     private Boolean removeAbandoned = true;  22 
 23     private Integer removeAbandonedTimeout = 180;  24 
 25     private Integer timeBetweenEvictionRunsMillis = 60000;  26 
 27     private Integer minEvictableIdleTimeMillis = 300000;  28 
 29     private String validationQuery = "SELECT 'x'";  30 
 31     private Boolean testWhileIdle = true;  32 
 33     private Boolean testOnBorrow = false;  34 
 35     private Boolean testOnReturn = false;  36 
 37     private Boolean poolPreparedStatements = true;  38 
 39     private Integer maxPoolPreparedStatementPerConnectionSize = 50;  40 
 41     private String filters = "stat";  42 
 43     public void config(DruidDataSource dataSource) {  44  dataSource.setDbType(JdbcConstants.MYSQL);  45  dataSource.setUrl(url);  46  dataSource.setUsername(username);  47  dataSource.setPassword(password);  48  dataSource.setDriverClassName(driverClassName);  49         dataSource.setInitialSize(initialSize);     // 定義初始鏈接數
 50         dataSource.setMinIdle(minIdle);             // 最小空閒
 51         dataSource.setMaxActive(maxActive);         // 定義最大鏈接數
 52         dataSource.setMaxWait(maxWait);             // 獲取鏈接等待超時的時間
 53         dataSource.setRemoveAbandoned(removeAbandoned); // 超過期間限制是否回收
 54         dataSource.setRemoveAbandonedTimeout(removeAbandonedTimeout); // 超過期間限制多長  55 
 56         // 配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接,單位是毫秒
 57  dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  58         // 配置一個鏈接在池中最小生存的時間,單位是毫秒
 59  dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  60         // 用來檢測鏈接是否有效的sql,要求是一個查詢語句
 61  dataSource.setValidationQuery(validationQuery);  62         // 申請鏈接的時候檢測
 63  dataSource.setTestWhileIdle(testWhileIdle);  64         // 申請鏈接時執行validationQuery檢測鏈接是否有效,配置爲true會下降性能
 65  dataSource.setTestOnBorrow(testOnBorrow);  66         // 歸還鏈接時執行validationQuery檢測鏈接是否有效,配置爲true會下降性能
 67  dataSource.setTestOnReturn(testOnReturn);  68         // 打開PSCache,而且指定每一個鏈接上PSCache的大小
 69  dataSource.setPoolPreparedStatements(poolPreparedStatements);  70  dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);  71         // 屬性類型是字符串,經過別名的方式配置擴展插件,經常使用的插件有:  72         // 監控統計用的filter:stat  73         // 日誌用的filter:log4j  74         // 防護SQL注入的filter:wall
 75         try {  76  dataSource.setFilters(filters);  77         } catch (SQLException e) {  78  e.printStackTrace();  79  }  80  }  81 
 82     public String getUrl() {  83         return url;  84  }  85 
 86     public void setUrl(String url) {  87         this.url = url;  88  }  89 
 90     public String getUsername() {  91         return username;  92  }  93 
 94     public void setUsername(String username) {  95         this.username = username;  96  }  97 
 98     public String getPassword() {  99         return password; 100  } 101 
102     public void setPassword(String password) { 103         this.password = password; 104  } 105 
106     public String getDriverClassName() { 107         return driverClassName; 108  } 109 
110     public void setDriverClassName(String driverClassName) { 111         this.driverClassName = driverClassName; 112  } 113 
114     public Integer getInitialSize() { 115         return initialSize; 116  } 117 
118     public void setInitialSize(Integer initialSize) { 119         this.initialSize = initialSize; 120  } 121 
122     public Integer getMinIdle() { 123         return minIdle; 124  } 125 
126     public void setMinIdle(Integer minIdle) { 127         this.minIdle = minIdle; 128  } 129 
130     public Integer getMaxActive() { 131         return maxActive; 132  } 133 
134     public void setMaxActive(Integer maxActive) { 135         this.maxActive = maxActive; 136  } 137 
138     public Integer getMaxWait() { 139         return maxWait; 140  } 141 
142     public void setMaxWait(Integer maxWait) { 143         this.maxWait = maxWait; 144  } 145 
146     public Integer getTimeBetweenEvictionRunsMillis() { 147         return timeBetweenEvictionRunsMillis; 148  } 149 
150     public void setTimeBetweenEvictionRunsMillis(Integer timeBetweenEvictionRunsMillis) { 151         this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis; 152  } 153 
154     public Integer getMinEvictableIdleTimeMillis() { 155         return minEvictableIdleTimeMillis; 156  } 157 
158     public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) { 159         this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; 160  } 161 
162     public String getValidationQuery() { 163         return validationQuery; 164  } 165 
166     public void setValidationQuery(String validationQuery) { 167         this.validationQuery = validationQuery; 168  } 169 
170     public Boolean getTestWhileIdle() { 171         return testWhileIdle; 172  } 173 
174     public void setTestWhileIdle(Boolean testWhileIdle) { 175         this.testWhileIdle = testWhileIdle; 176  } 177 
178     public Boolean getTestOnBorrow() { 179         return testOnBorrow; 180  } 181 
182     public void setTestOnBorrow(Boolean testOnBorrow) { 183         this.testOnBorrow = testOnBorrow; 184  } 185 
186     public Boolean getTestOnReturn() { 187         return testOnReturn; 188  } 189 
190     public void setTestOnReturn(Boolean testOnReturn) { 191         this.testOnReturn = testOnReturn; 192  } 193 
194     public Boolean getPoolPreparedStatements() { 195         return poolPreparedStatements; 196  } 197 
198     public void setPoolPreparedStatements(Boolean poolPreparedStatements) { 199         this.poolPreparedStatements = poolPreparedStatements; 200  } 201 
202     public Integer getMaxPoolPreparedStatementPerConnectionSize() { 203         return maxPoolPreparedStatementPerConnectionSize; 204  } 205 
206     public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) { 207         this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize; 208  } 209 
210     public String getFilters() { 211         return filters; 212  } 213 
214     public void setFilters(String filters) { 215         this.filters = filters; 216  } 217 
218     public Boolean getRemoveAbandoned() { 219         return removeAbandoned; 220  } 221 
222     public void setRemoveAbandoned(Boolean removeAbandoned) { 223         this.removeAbandoned = removeAbandoned; 224  } 225 
226     public Integer getRemoveAbandonedTimeout() { 227         return removeAbandonedTimeout; 228  } 229 
230     public void setRemoveAbandonedTimeout(Integer removeAbandonedTimeout) { 231         this.removeAbandonedTimeout = removeAbandonedTimeout; 232  } 233 }
View Code

 

 1 @Component  2 @ConfigurationProperties(prefix = "biz.datasource")  3 public class MutiDataSourceProperties {  4 
 5     private String url;  6 
 7     private String username;  8 
 9     private String password; 10 
11     public void config(DruidDataSource dataSource) { 12  dataSource.setUrl(url); 13  dataSource.setUsername(username); 14  dataSource.setPassword(password); 15  } 16 
17     public String getUrl() { 18         return url; 19  } 20 
21     public void setUrl(String url) { 22         this.url = url; 23  } 24 
25     public String getUsername() { 26         return username; 27  } 28 
29     public void setUsername(String username) { 30         this.username = username; 31  } 32 
33     public String getPassword() { 34         return password; 35  } 36 
37     public void setPassword(String password) { 38         this.password = password; 39  } 40 }
View Code

 

而後定義配置類:

 1 @Configuration  2 @EnableTransactionManagement(order = 2)  3 @MapperScan(basePackages = {"com.code.springbootmultisource.common.dao.repository"})  4 public class MybatisPlusConfig {  5 
 6  @Autowired  7  DruidProperties druidProperties;  8 
 9  @Autowired 10  MutiDataSourceProperties mutiDataSourceProperties; 11 
12     /** 13  * 核心數據源 14      */
15     private DruidDataSource coreDataSource() { 16         DruidDataSource dataSource = new DruidDataSource(); 17  druidProperties.config(dataSource); 18         return dataSource; 19  } 20 
21     /** 22  * 另外一個數據源 23      */
24     private DruidDataSource bizDataSource() { 25         DruidDataSource dataSource = new DruidDataSource(); 26  druidProperties.config(dataSource); 27  mutiDataSourceProperties.config(dataSource); 28         return dataSource; 29  } 30 
31     /** 32  * 單數據源鏈接池配置 33      */
34  @Bean 35     @ConditionalOnProperty(prefix = "code", name = "muti-datasource-open", havingValue = "false") 36     public DruidDataSource singleDatasource() { 37         return coreDataSource(); 38  } 39 
40 
41     /** 42  * 多數據源鏈接池配置 43      */
44  @Bean 45     @ConditionalOnProperty(prefix = "code", name = "muti-datasource-open", havingValue = "true") 46     public DynamicDataSource mutiDataSource() { 47 
48         DruidDataSource coreDataSource = coreDataSource(); 49         DruidDataSource bizDataSource = bizDataSource(); 50 
51         try { 52  coreDataSource.init(); 53  bizDataSource.init(); 54         } catch (SQLException sql) { 55  sql.printStackTrace(); 56  } 57 
58         DynamicDataSource dynamicDataSource = new DynamicDataSource(); 59         HashMap<Object, Object> hashMap = new HashMap<>(); 60  hashMap.put(DSEnum.DATA_SOURCE_CORE, coreDataSource); 61  hashMap.put(DSEnum.DATA_SOURCE_BIZ, bizDataSource); 62  dynamicDataSource.setTargetDataSources(hashMap); 63  dynamicDataSource.setDefaultTargetDataSource(coreDataSource); 64         return dynamicDataSource; 65  } 66 
67 }

 

實體類

 1 @TableName(value = "t_user")  2 public class User extends Model<User> {  3 
 4     private static final long serialVersionUID = 1L;  5 
 6     @TableId(value="id", type= IdType.AUTO)  7     private Integer id;  8 
 9     private String username;  10 
 11     private String name;  12 
 13     private String password;  14 
 15     private String salt;  16 
 17     private String phone;  18 
 19     private String tips;  20 
 21     private Integer state;  22 
 23     private Date createdTime;  24 
 25     private Date updatedTime;  26 
 27     public static long getSerialVersionUID() {  28         return serialVersionUID;  29  }  30 
 31     public Integer getId() {  32         return id;  33  }  34 
 35     public void setId(Integer id) {  36         this.id = id;  37  }  38 
 39     public String getUsername() {  40         return username;  41  }  42 
 43     public void setUsername(String username) {  44         this.username = username;  45  }  46 
 47     public String getName() {  48         return name;  49  }  50 
 51     public void setName(String name) {  52         this.name = name;  53  }  54 
 55     public String getPassword() {  56         return password;  57  }  58 
 59     public void setPassword(String password) {  60         this.password = password;  61  }  62 
 63     public String getSalt() {  64         return salt;  65  }  66 
 67     public void setSalt(String salt) {  68         this.salt = salt;  69  }  70 
 71     public String getPhone() {  72         return phone;  73  }  74 
 75     public void setPhone(String phone) {  76         this.phone = phone;  77  }  78 
 79     public String getTips() {  80         return tips;  81  }  82 
 83     public void setTips(String tips) {  84         this.tips = tips;  85  }  86 
 87     public Integer getState() {  88         return state;  89  }  90 
 91     public void setState(Integer state) {  92         this.state = state;  93  }  94 
 95     public Date getCreatedTime() {  96         return createdTime;  97  }  98 
 99     public void setCreatedTime(Date createdTime) { 100         this.createdTime = createdTime; 101  } 102 
103     public Date getUpdatedTime() { 104         return updatedTime; 105  } 106 
107     public void setUpdatedTime(Date updatedTime) { 108         this.updatedTime = updatedTime; 109  } 110 
111  @Override 112     protected Serializable pkVal() { 113         return this.id; 114  } 115 
116 }
View Code

 

定義DAO

 

1 public interface UserMapper extends BaseMapper<User> { 2 
3 }
View Code

 

定義Service

 

 1 @Service  2 public class UserService {  3 
 4  @Resource  5     private UserMapper userMapper;  6 
 7     public User findById(Integer id) {  8         return userMapper.selectById(id);  9  } 10 
11     @DataSource(name = DSEnum.DATA_SOURCE_BIZ) 12     public User findById1(Integer id) { 13         return userMapper.selectById(id); 14  } 15 }

 

這裏惟一要說明的就是我在方法findById1()上面增長了註解@DataSource(name = DSEnum.DATA_SOURCE_BIZ),這樣這個方法就會訪問biz數據庫。

注意,不加註解就會訪問默認數據庫pos。

測試

最後編寫一個簡單的測試,我只測試findById()方法和findById1()方法,看它們是否訪問的是不一樣的數據源。

 1 @RunWith(SpringRunner.class)  2 @SpringBootTest  3 public class SpringbootMultisourceApplicationTests {  4 
 5     private static final Logger LOGGER = LoggerFactory.getLogger(SpringbootMultisourceApplicationTests.class);  6 
 7  @Resource  8     private UserService userService;  9 
10  @Test 11     public void contextLoads() { 12 
13         User user = userService.findById(1); 14         LOGGER.info("核心數據庫user = " + user.getUsername()); 15 
16         User user1 = userService.findById1(1); 17         LOGGER.info("biz數據庫user = " + user1.getUsername()); 18  } 19 
20 }

顯示結果:

核心數據庫user = admin 數據源設置爲: dataSourceBiz biz數據庫user = admin
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息