切面动态数据源&数据库连接池org.mybatis
1,对接口interface使用切面需要2.0以上版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
</parent>,
2,需要在某一个数据源上加@Primary ,否则默认装配数据源会报找到多个数据源错误
SpringBoot 实现动态切换数据源 https://mp.weixin.qq.com/s/R8vTrINMOwxhr2lfzyDrtQ
扫描类引入的是 tk.mybatis.spring.annotation.MapperScan
自定义MyBaseMapper不能放在scan扫描包内
import tk.mybatis.mapper.common.Mapper;
public interface MyBaseMapper<T> extends Mapper<T> {
}
本质就是切换数据源
org.mybatis
DateSource 定义注解
DateSourceContext 定义ThreadLocal上下文
DataSourceRouteAspect会拦截注解dataSource的方法,业务方法之前设置数据源,设置到ThreadLocal中
也可根据业务参数自主设置数据源,达到分库效果
DruidConfig 配置多数据源
MybatisConfig 扫描sql配置类
RouteDataSource 通过继承AbstractRoutingDataSource重写,获取ThreadLocal中的数据源
@Target({ ElementType.METHOD,ElementType.TYPE,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
String value() default "";
}
public class DataSourceContext {
private static final ThreadLocal<String> context = new ThreadLocal<>();
public static void setDataSource(String value){
context.set(value);
}
public static String getDataSource(){
return context.get();
}
public static void clearDataSource(){
context.remove();
}
}
@Aspect
@Component
public class DataSourceRouteAspect {
@Before("@annotation(dataSource)")
public void selectDateSource(JoinPoint point, DataSource dataSource){
String value = dataSource.value();
DataSourceContext.setDataSource(value);
}
@After("@annotation(dataSource)")
public void removeDataSource(JoinPoint point, DataSource dataSource){
DataSourceContext.clearDataSource();
}
}
@Configuration
public class DruidConfig {
// @Value("${mysql.one.aliasName}")
// private String aliasNameOne;
// @Primary
@Bean(name="dataSourceOne",initMethod = "init",destroyMethod = "close")
@ConfigurationProperties(prefix = "mysql.one")
public DruidDataSource dataSourceOne(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setQueryTimeout(300);
dataSource.setTestWhileIdle(true);
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(true);
dataSource.setTimeBetweenEvictionRunsMillis(600000);
dataSource.setMinEvictableIdleTimeMillis(300000);
return dataSource;
}
// @Bean(name="dataSourceTwo",initMethod = "init",destroyMethod = "close")
// @ConfigurationProperties(prefix = "mysql.two")
// public DruidDataSource dataSourceOne(){
// return dataSource;
// }
@Bean(name = "routeDataSource")
public RouteDataSource dataSource(@Qualifier("dataSourceOne")DruidDataSource dataSourceOne
// ,@Qualifier("dataSourceTwo")DruidDataSource dataSourceTwo
){
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("dataSourceOne",dataSourceOne);
// targetDataSources.put("dataSourceTwo",dataSourceTwo);
RouteDataSource dataSource = new RouteDataSource();
dataSource.setTargetDataSources(targetDataSources);
dataSource.setDefaultTargetDataSource(dataSourceOne);
System.out.println("routeDataSource******************"+dataSource);
return dataSource;
}
}
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import tk.mybatis.spring.annotation.MapperScan
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
@MapperScan("cn.com.xmh.ibatisMapper")
public class MybatisConfig {
@Autowired
private RouteDataSource routeDataSource;
@Bean(name="SqlSessionFactory")
// @Primary
public SqlSessionFactoryBean sqlSessionFactoryBean(){
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("mytest",transactionFactory,routeDataSource);
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(environment);
configuration.setMapUnderscoreToCamelCase(true);
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(routeDataSource);
sqlSessionFactoryBean.setConfiguration(configuration);
return sqlSessionFactoryBean;
}
@Bean(name="transactionManager")
@Primary
public PlatformTransactionManager transactionManager(){
return new DataSourceTransactionManager(routeDataSource);
}
}
mapper配置类
import cn.com.config.dbConfig.DataSource;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface MyTestIbatis extends BaseMapper<String>{
@DataSource("dataSourceOne")
@Select("select id from tbl_user")
List<String> selectStr();
}
import tk.mybatis.mapper.common.Mapper;
public interface MyBaseMapper<T> extends Mapper<T> {
}
@Autowired
MyTestIbatis myTestIbatis;
myTestIbatis.selectStr()
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
spring.datasource.url=jdbc:mysql://127.0.0.1/xmh
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mysql.one.url=jdbc:mysql://127.0.0.1/xmh
mysql.one.userName=root
mysql.one.password=admin
mysql.one.initialSize= 5
mysql.one.minIdle= 5
mysql.one.maxActive= 20
mysql.one.maxWait= 6000
mysql.one.validationQuery= select 1 from dual
mysql.one.drever-class-name= com.mysql.jdbc.Driver
public class RouteDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContext.getDataSource();
}
}

浙公网安备 33010602011771号