通过AOP实现Mybatis多数据源切换:
yml文件配置:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印mybatis sql日志
spring:
datasource:
druid:
master-db:
url: jdbc:mysql://120.0.0.1:3306/sydtjc
username: root
password: root
mysql-db:
url: jdbc:mysql://120.0.0.1:3306/ggfw
username: root
password: root
bjggfw-db:
url: jdbc:mysql://120.0.0.1:3306/ggfw_ggfw
username: root
password: root
自定义注解
import java.lang.annotation.*;
@Documented
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSourceAnnotation {
DBTypeEnum value() default DBTypeEnum.Master;
}
自定义类型:
public enum DBTypeEnum {
Master("master"), Oracle("oracle"), Mysql("mysql"), Bjggfw("bjggfw");
private String value;
DBTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
公共方法:
public class DbContextHolder {
public static final DBTypeEnum DEFAULT_DATA_SOURCE = DBTypeEnum.Master;
private static final ThreadLocal<DBTypeEnum> CONTEXT_HOLDER = new ThreadLocal<>();
static {
setDefaultDataSource(); // 默认指定master
}
/**
* 设置默认数据源
*/
public static void setDefaultDataSource() {
CONTEXT_HOLDER.set(DEFAULT_DATA_SOURCE);
}
/**
* 取得当前数据源
*
* @return
*/
public static DBTypeEnum getDbType() {
return CONTEXT_HOLDER.get();
}
/**
* 设置数据源
*
* @param dbTypeEnum
*/
public static void setDbType(DBTypeEnum dbTypeEnum) {
CONTEXT_HOLDER.set(dbTypeEnum);
}
/**
* 清除上下文数据
*/
public static void clearDbType() {
CONTEXT_HOLDER.remove();
}
}
切面类:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class DynamicDataSourceAspect {
@Around("@within(com.ylz.bjyf.common.multipledatasource.DataSourceAnnotation) || @annotation(com.ylz.bjyf.common.multipledatasource.DataSourceAnnotation)")
public Object before(ProceedingJoinPoint point) throws Throwable {
Class<?> clazz = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
try {
if (clazz.isAnnotationPresent(DataSourceAnnotation.class)) {
DataSourceAnnotation annotation = clazz.getAnnotation(DataSourceAnnotation.class);
DbContextHolder.setDbType(annotation.value());
}
Method method = clazz.getMethod(signature.getName(), signature.getParameterTypes());
if (method.isAnnotationPresent(DataSourceAnnotation.class)) {
// 根据注解设置数据源
DataSourceAnnotation annotation = method.getAnnotation(DataSourceAnnotation.class);
DbContextHolder.setDbType(annotation.value());
}
return point.proceed();
} catch (Exception e) {
e.printStackTrace();
} finally {
DbContextHolder.setDbType(DBTypeEnum.Master);
}
return null;
}
}
多数据源配置类:
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 取得当前使用哪个数据源
*
* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}
}
配置类:
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.ylz.bjyf.common.multipledatasource.DBTypeEnum;
import com.ylz.bjyf.common.multipledatasource.DynamicDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@EnableTransactionManagement
@Configuration
@MapperScan({
"org.mohrss.leaf.**.entity", "com.ylz.bjyf.**.mapper" }) // 注意,不要扫描jpa接口,否则使用jpa时会出现问题
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
@Bean(name = "masterDb")
@ConfigurationProperties(prefix = "spring.datasource.druid.master-db")
public DataSource masterDb() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "mysqlDb")
@ConfigurationProperties(prefix = "spring.datasource.druid.mysql-db")
public DataSource mysqlDb() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "bjggfwDb")
@ConfigurationProperties(prefix = "spring.datasource.druid.bjggfw-db")
public DataSource bjggfwDb() {
return DruidDataSourceBuilder.create().build();
}
/**
* 动态数据源配置
*
* @return
*/
@Bean
@Primary
public DynamicDataSource dynamicDataSource(@Qualifier("masterDb") DataSource masterDb,
@Qualifier("mysqlDb") DataSource mysqlDb,
@Qualifier("bjggfwDb") DataSource bjggfwDb) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>(2);
targetDataSources.put(DBTypeEnum.Master, masterDb);
targetDataSources.put(DBTypeEnum.Mysql, mysqlDb);
targetDataSources.put(DBTypeEnum.Bjggfw, bjggfwDb);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(masterDb);
return dynamicDataSource;
}
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource) throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dynamicDataSource);
// sqlSessionFactory.setMapperLocations(new
// PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*/*Mapper.xml"));
MybatisConfiguration configuration = new MybatisConfiguration();
// configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
configuration.setMapUnderscoreToCamelCase(true);
configuration.setCacheEnabled(false);
sqlSessionFactory.setConfiguration(configuration);
sqlSessionFactory.setPlugins(new Interceptor[]{
// performanceInterceptor(),OptimisticLockerInterceptor()
paginationInterceptor() // 添加分页功能
});
// sqlSessionFactory.setGlobalConfig(globalConfiguration());
return sqlSessionFactory.getObject();
}
}
还没有评论,来说两句吧...