spring:注意:根据springboot的版本不同,有不同的写法,在springboot2.0的版本中,注意url要写成jdbc-url,尝试过url的话会报错
datasource:
master:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/数据库名
username: root
password: root
slave:
type: com.alibaba.druid.pool.DruidDataSource
platform: oracle
jdbc-url: jdbc:oracle:thin:@localhost:1521:数据库名
username: system
password: system
#指定数据源的全限定名
driver-class-name: oracle.jdbc.driver.OracleDriver
@Configuration
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
public class DynamicDataSourceConfig {
@Bean(DataSourceConstants.MASTER)
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(DataSourceConstants.SLAVE)
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public DataSource dynamicDataSource() {
Map<Object, Object> dataSourceMap = new HashMap<>(2);
dataSourceMap.put(DataSourceConstants.MASTER, masterDataSource());
dataSourceMap.put(DataSourceConstants.SLAVE, slaveDataSource());
//设置动态数据源
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
return dynamicDataSource;
}
}
public class DataSourceConstants {
public final static String MASTER = "master";
public final static String SLAVE = "slave";
}
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getContextKey();
}
}
public class DynamicDataSourceContextHolder {
/*这是为了线程安全*/
private static final ThreadLocal<String> DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>();
/* 设置/切换数据源*/
public static void setContextKey(String key) {
DATASOURCE_CONTEXT_KEY_HOLDER.set(key);
}
/* 获取数据源名称 */
public static String getContextKey() {
String key = DATASOURCE_CONTEXT_KEY_HOLDER.get();
return key == null ? DataSourceConstants.MASTER : key;
}
/*删除当前数据源名称*/
public static void removeContextKey() {
DATASOURCE_CONTEXT_KEY_HOLDER.remove();
}
}
@Target({ ElementType.METHOD, ElementType.TYPE })定义数据源切面
@Retention(RetentionPolicy.RUNTIME)
public @interface DbAnnotation {
/**
* 数据源名称,默认master
*/
String value() default DataSourceConstants.MASTER;
}
@Aspect
@Component
public class DynamicDataSourceAspect {
//拦截DbAnnotation
@Pointcut("@within(com.example.constant.DbAnnotation)"+"||@annotation(com.example.constant.DbAnnotation)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String dsKey = this.getDSAnnotation(joinPoint).value();
DynamicDataSourceContextHolder.setContextKey(dsKey);
try {
return joinPoint.proceed();
} catch (Exception ex) {
throw ex;
} finally {
DynamicDataSourceContextHolder.removeContextKey();
}
}
/**
* 根据类或方法获取数据源注解
*/
private DbAnnotation getDSAnnotation(ProceedingJoinPoint joinPoint) {
//mybatis生成的代理类,所以获取它的接口来获取DbAnnotation注解信息
Class<?> targetClass = joinPoint.getTarget().getClass().getInterfaces()[0];
DbAnnotation dsAnnotation = targetClass.getAnnotation(DbAnnotation.class);
// 先判断类的注解,再判断方法注解
if (Objects.nonNull(dsAnnotation)) {
return dsAnnotation;
} else {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
DbAnnotation annotation = methodSignature.getMethod().getAnnotation(DbAnnotation.class);
return annotation;
}
}
}
@Mapper
public interface OrUserMapper extends BaseMapper<OrUser> {
@Select("select *from tb_user")
@DbAnnotation(DataSourceConstants.SLAVE)
List<OrUser> select();
}
@RequestMapping("/user/select")然后如果想要在同一个函数里面调用不同的数据库的话,此时不能将注解定义在函数上面,不然mybatis-plus会报错,因为mybatis-plus 默认来说是运行期间就只支持一种数据源,初始化的时候就已经决定了,无法动态转换。
public void test(){
List<OrUser> select = orUserMapper.select();
System.out.println(select.get(0));
}
@Mapper其实加和不加都可以,因为不加的话使用的是默认的数据源, 默认的就是mysql
//可以加或者不加也可以
@DbAnnotation(DataSourceConstants.MASTER)
public interface UserMapper extends BaseMapper<User> {
}
@Mapper测试:
public interface OrUserMapper extends BaseMapper<OrUser> {
@Select("select *from tb_user")
@DbAnnotation(DataSourceConstants.SLAVE)
List<OrUser> select();
}
public void select() {2.使用spring提供的一个依赖
List<OrUser> select = orUserMapper.select();
List<User> users = userMapper.selectList(null);
System.out.println(select.get(0));
System.out.println(users.get(0));
}
<dependency>配置文件:
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
spring:
datasource:
dynamic:
primary: master # 配置默认数据库
datasource:
#主库数据源
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/数据库名
username: root
password: root
slave:
type: com.alibaba.druid.pool.DruidDataSource
platform: oracle
url: jdbc:oracle:thin:@localhost:1521:数据库名
username: system
password: system
#指定数据源的全限定名
driver-class-name: oracle.jdbc.driver.OracleDriver
@DS("slave")
public void test(){
List<OrUser> select = userMapper.select();
System.out.println(select.get(0).getUsername());
}
免责申明:
本文系转载,版权归原作者所有,如若侵权请联系我们进行删除!
《数据治理行业实践白皮书》下载地址:https://fs80.cn/4w2atu
《数栈V6.0产品白皮书》下载地址:https://fs80.cn/cw0iw1
想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=bbs
同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术群」,交流最新开源技术信息,群号码:30537511,项目地址:https://github.com/DTStack