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
相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息