springboot项目多数据操作
这里的多数据的使用是定义切面和用注解的方式来实现的,使用的话相对于比较简单,在方法实现上面定义好注解,标明是哪个数据源的即可,不过一个方法不能同时使用多个数据源,要区别开来,可以单独对其他数据源的方法进行封装,处理好再返回即可
1.配置yml文件
这里我的master1和master2数据源都是mysql的,如果想要配置其他的数据源的话,可以自己修改master2,或者master3如此类推。
datasource:
master1:
username: root
password: tisson123!#
#password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
#用测试环境的库
jdbc-url: jdbc:mysql://116.85.22.202:3307/industrial_park?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
druid://...............连接池那些,自己搞
master2:
username: root
password: tisson123!#
#password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
#用测试环境的库
jdbc-url: jdbc:mysql://116.85.22.202:3307/business_management?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
druid: //.......连接池
2.配置config
DynamicDataSourceConfig
mport cn.tisson.yq.enterprise.common.DynamicDataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 添加此配置,否则 报`The dependencies of some of the beans in the application context form a cycle`
*/
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
@Configuration
@PropertySource("classpath:application.yml")
@MapperScan(basePackages = "cn.tisson.yq.enterprise.dao.mapper")
public class DynamicDataSourceConfig {
@Bean("master1")
@ConfigurationProperties(prefix = "spring.datasource.master1")
public DataSource master1DataSource() {
return DataSourceBuilder.create().build();
}
@Bean("master2")
@ConfigurationProperties(prefix = "spring.datasource.master2")
public DataSource master2DataSource() {
return DataSourceBuilder.create().build();
}
//设置动态数据源为主数据源
@Bean
@Primary
public DataSource dynamicDataSource() {
Map<Object, Object> dataSourceMap = new HashMap<>(2);
dataSourceMap.put("master1", master1DataSource());
dataSourceMap.put("master2", master2DataSource());
//设置动态数据源
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.setDefaultTargetDataSource(master1DataSource());
return dynamicDataSource;
}
}
3.然后设置一下动态数据源
DynamicDataSource
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 动态数据源
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getContextKey();
}
}
4.获取数据源
DynamicDataSourceContextHolder
public class DynamicDataSourceContextHolder {
/**
* 动态数据源名称上下文
*/
private static final ThreadLocal<String> DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>();
/**
* 设置数据源
* @param key
*/
public static void setContextKey(String key){
System.out.println("切换数据源"+key);
DATASOURCE_CONTEXT_KEY_HOLDER.set(key);
}
/**
* 获取数据源名称
* @return
*/
public static String getContextKey(){
String key = DATASOURCE_CONTEXT_KEY_HOLDER.get();
return key == null?"master1":key;
}
/**
* 删除当前数据源名称
*/
public static void removeContextKey(){
DATASOURCE_CONTEXT_KEY_HOLDER.remove();
}
}
5.定义多数据源的切面类
DynamicDataSourceAspect
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(cn.tisson.yq.enterprise.aspect.DS)")
public void dataSourcePointCut(){
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
String dsKey = getDSAnnotation(joinPoint).value();
DynamicDataSourceContextHolder.setContextKey(dsKey);
try{
return joinPoint.proceed();
}finally {
DynamicDataSourceContextHolder.removeContextKey();
}
}
/**
* 根据类或方法获取数据源注解
* @param joinPoint
* @return
*/
private DS getDSAnnotation(ProceedingJoinPoint joinPoint){
Class<?> targetClass = joinPoint.getTarget().getClass();
DS dsAnnotation = targetClass.getAnnotation(DS.class);
// 先判断类的注解,再判断方法注解
if(Objects.nonNull(dsAnnotation)){
return dsAnnotation;
}else{
MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
return methodSignature.getMethod().getAnnotation(DS.class);
}
}
}
6.最后定义一个注解就可以使用了
这里用DS名称,DataSource嘛,自己喜欢
/**
* 自定义数据源注解
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
/**
* 默认数据源名称
* @return
*/
String value() default "master1";
使用
不指定数据源的话默认是使用master1的数据源的,使用数据源的话如:
@DS("master2") //数据源2
@Override
public AppQyJbxxVo findOne(String uniscId) {
return appQyJbxxMapper.findByUniscId(uniscId);
}
好的这就解决了,也是参考回来的,方便存储用作学习