栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybatis动态数据源配置(附自定义注解实现数据源切换)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mybatis动态数据源配置(附自定义注解实现数据源切换)

在做DB数据迁移需求的时候要用到多数据源,正好整理下

实际用到以下几个类

配置文件

#端口
server.port: 8080
spring.application.name: lzqdemo

# mysql
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
db.username=root
db.password=123456
#数据库2
db2.driverClassName=com.mysql.jdbc.Driver
db2.url=jdbc:mysql://127.0.0.1:3306/db2?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false
db2.username=root
db2.password=123456
启动类

一定要加上exclude = {DataSourceAutoConfiguration.class}

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

//移除默认数据库配置类
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class DbDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DbDemoApplication.class, args);
    }

}
DBConfig配置
@Configuration
public class DBConfig {

	private static HLogger logger = HLoggerFactory.getLogger(DBConfig.class);
	
	@Autowired
	@Qualifier("dynamicDataSource")
	private DataSource dynamicDataSource;

	//当前主数据源
	@Bean(name = "dbOne")
	@ConfigurationProperties(prefix = "db")
	public DataSource dataSource1() {
		logger.info(">>>>>>>>>>> masterDataSource config init.");
		return DataSourceBuilder.create().build();
	}


	//需要迁移的旧DB数据源
	@Bean(name = "dbTwo")
	@ConfigurationProperties(prefix = "db2")
	public DataSource dataSource2() {
		logger.info(">>>>>>>>>>> slaveDataSource config init.");
		return DataSourceBuilder.create().build();
	}
	
	@Bean
	public MySqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
		MySqlSessionFactoryBean sqlSessionFactoryBean = new MySqlSessionFactoryBean();
		sqlSessionFactoryBean.setDaoBasePackage("自己项目的mapper包路径");
		sqlSessionFactoryBean.setDataSource(dynamicDataSource);
		sqlSessionFactoryBean.setModelBasePackage("自己项目的entity路径");
		sqlSessionFactoryBean.setDaoSuffix("Dao");
		sqlSessionFactoryBean.setModelSuffix("Entity");
		Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/mapper*.xml");
		sqlSessionFactoryBean.setMapperLocations(resources);

		//加入本地config配置,确保转出的字段如果为null可以存在map内
		Resource resources2 = new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml");
		sqlSessionFactoryBean.setConfigLocation(resources2);
		return sqlSessionFactoryBean;
	}

	@Bean
	public PlatformTransactionManager transactionManager() {
		return new DataSourceTransactionManager(dynamicDataSource);
	}
}

注意这里事务一样要配置,不然切换数据源后不会生效

	  
	@Bean
	public PlatformTransactionManager transactionManager() {
		return new DataSourceTransactionManager(dynamicDataSource);
	}
DataSourceConfig配置
@Component
//@ConfigurationProperties("spring.datasource")
public class DataSourceConfig {

    @Autowired
    @Qualifier("dbOne")
    DataSource dataSource1;

    @Autowired
    @Qualifier("dbTwo")
    DataSource dataSource2;

    
    @Primary
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 默认数据源
        dynamicDataSource.setDefaultTargetDataSource(dataSource1);
        // 配置多数据源
        Map dsMap = new HashMap<>();
        dsMap.put("dbOne", dataSource1);
        dsMap.put("dbTwo", dataSource2);

        dynamicDataSource.setTargetDataSources(dsMap);
        return dynamicDataSource;
    }

  
}
DataSourceUtil
public class DataSourceUtil {
    
    public static final String DEFAULT_DS = "dbOne";
    
    private static final ThreadLocal contextHolder = new ThreadLocal<>();

    
    public static void setDB(String dbType) {
        contextHolder.set(dbType);
    }

    
    public static String getDB() {
        return (contextHolder.get());
    }

    
    public static void clearDB() {
        contextHolder.remove();
    }
}
DynamicDataSource
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceUtil.getDB();
    }
}
AOP实现动态切换数据源注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface TargetDataSource {
    String connName() default "dbOne";
}
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class DataSourceExchange {

    @Before("@annotation(TargetDataSource)")
    public void before(JoinPoint joinPoint){
        MethodSignature sign = (MethodSignature) joinPoint.getSignature();
        Method method = sign.getMethod();
        boolean isMethodAop= method.isAnnotationPresent(TargetDataSource.class);
        if (isMethodAop){
            TargetDataSource datasource = method.getAnnotation(TargetDataSource.class);
            DataSourceUtil.setDB(datasource.connName());
            //DataSourceHolder.setDataSources(datasource.connName());
        }else {
            if (joinPoint.getTarget().getClass().isAnnotationPresent(TargetDataSource.class)){
                TargetDataSource datasource = joinPoint.getTarget().getClass().getAnnotation(TargetDataSource.class);
                DataSourceUtil.setDB(datasource.connName());
                //DataSourceHolder.setDataSources(datasource.connName());
            }
        }
    }

    @After("@annotation(TargetDataSource)")
    public void after(){
        DataSourceUtil.clearDB();
        //DataSourceHolder.clearDataSource();
    }
}
实际使用

connName传你要使用的数据源就可以了

	@TargetDataSource(connName = "dbTwo")
    public List> getListMap(String tableName, Map fieldsMap, String startTime,String endTime,int queryType){
        Map map = new HashMap<>();
        map.put("tableName", tableName);
        map.put("fieldsMap", fieldsMap);
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        if (queryType==0){
            return dataMigrationDao.queryByCreateDateList(map);
        }else if (queryType==1){
            return dataMigrationDao.queryByCreateTimeList(map);
        }else if (queryType==3){
            return dataMigrationDao.queryByModifyDateList(map);
        }else if (queryType==4){
            return dataMigrationDao.queryByUpdateTimeList(map);
        }
        return new ArrayList<>();
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/998630.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号