springboot+mybatis框架搭建--6.配置myba

2019-03-08  本文已影响0人  小狼在IT

模拟一个读写分离了的数据库端:


image.png

mytest数据库的user数据:


image.png

mytest2数据库的user数据:


image.png

1.配置application.properties
把原来的 spring.datasource 配置去掉,配置成如下信息:

    #-------------------------------------------------------------
    #master.datasource begin
    master.datasource.type=com.alibaba.druid.pool.DruidDataSource
    master.datasource.url=jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf-8&serverTimeZone=GMT%2B8
    master.datasource.driverClassName=com.mysql.cj.jdbc.Driver
    master.datasource.username=${dbUserName}
    master.datasource.password=${dbpsw}
    master.datasource.initialSize=5
    master.datasource.minIdle=20
    master.datasource.maxActive=50
    master.datasource.maxWait=30000
    master.datasource.timeBetweenEvictionRunsMillis=60000
    master.datasource.minEvictableIdleTimeMillis=300000
    master.datasource.validationQuery=SELECT 1 
    master.datasource.testWhileIdle=true
    master.datasource.testOnBorrow=false
    master.datasource.testOnReturn=false
    master.datasource.poolPreparedStatements=true
    master.datasource.maxPoolPreparedStatementPerConnectionSize=20
    master.datasource.filters=stat,wall,slf4j
    master.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    master.datasource.useGlobalDataSourceStat=true
    #master.datasource end
    #-------------------------------------------------------------
    
    #-------------------------------------------------------------
    #slave.datasource begin
    slave.datasource.type=com.alibaba.druid.pool.DruidDataSource
    slave.datasource.url=jdbc:mysql://localhost:3306/mytest2?useUnicode=true&characterEncoding=utf-8&serverTimeZone=GMT%2B8
    slave.datasource.driverClassName=com.mysql.cj.jdbc.Driver
    slave.datasource.username=${dbUserName}
    slave.datasource.password=${dbpsw}
    slave.datasource.initialSize=5
    slave.datasource.minIdle=20
    slave.datasource.maxActive=50
    slave.datasource.maxWait=30000
    slave.datasource.timeBetweenEvictionRunsMillis=60000
    slave.datasource.minEvictableIdleTimeMillis=300000
    slave.datasource.validationQuery=SELECT 1 
    slave.datasource.testWhileIdle=true
    slave.datasource.testOnBorrow=false
    slave.datasource.testOnReturn=false
    slave.datasource.poolPreparedStatements=true
    slave.datasource.maxPoolPreparedStatementPerConnectionSize=20
    slave.datasource.filters=stat,wall,slf4j
    slave.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    slave.datasource.useGlobalDataSourceStat=true
    #slave.datasource end
    #-------------------------------------------------------------

2.工具类--数据库上下文

    public class DataSourceContextHolder {
        public enum DbType{
            MASTER,SLAVE
        }
        private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<DbType>(){
            @Override
            protected DbType initialValue() {
                return DbType.MASTER;
            }
        };
    
        public static void setDBType(DbType dbType) {
    
            if(dbType==null) {
                throw new NullPointerException();
            }
            contextHolder.set(dbType);
        }
        public static DbType getDBType() {
            return contextHolder.get()==null?DbType.MASTER:contextHolder.get();
        }
        public static void clearDBType() {
            contextHolder.remove();
        }
    }

3.工具类--存储数据源

    @Slf4j
    public class MultipleDataSource extends AbstractRoutingDataSource {
    
        @Override
        public Logger getParentLogger() {
            return null;
        }
    
        @Override
        protected Object determineCurrentLookupKey() {
            log.debug("----------------------------use DataSouce:" + DataSourceContextHolder.getDBType());
            return DataSourceContextHolder.getDBType();
        }
    
    }

4.工具类--从数据库使用标记

    @Target({ElementType.METHOD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface SlaveConnection {
    }

5.工具类--配合SlaveConnection的Aspect

    @Aspect
    @Component
    @Slf4j
    public class SlaveConnectionInterceptor  {
    
        @Around("@annotation(SlaveConnection)")
        public Object proceed(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            try {
                log.info("set database connection to salve");
                DataSourceContextHolder.setDBType(DataSourceContextHolder.DbType.SLAVE);
                Object result = proceedingJoinPoint.proceed();
                return result;
            }finally {
                DataSourceContextHolder.clearDBType();
                log.info("restore database connection");
            }
        }
    }

6.配置数据源

    @Configuration
    public class DataSourceConfiguration {
        @Value("${master.datasource.type}")
        private Class<? extends DataSource> dataSourceType;
    
        @Bean(name = "masterDatasource")
        @Primary
        @ConfigurationProperties(prefix = "master.datasource")
        public DataSource masterDatasource() {
            System.out.println("-------------------- writeDataSource init ---------------------");
            return DataSourceBuilder.create().type(dataSourceType).build();
        }
    
        @Bean(name = "slaveDatasource")
        @ConfigurationProperties(prefix = "slave.datasource")
        public DataSource slaveDatasource() {
            System.out.println("-------------------- readDataSourceOne init ---------------------");
            DataSource ds = DataSourceBuilder.create().type(dataSourceType).build();
            System.out.println("-------------------- readDataSourceOne done ---------------------");
            return ds;
        }

7.配置mybatis使用多数据源

    /**
     * 必须等DataSourceConfiguration加载完才加载
     */
    @Configuration
    @AutoConfigureAfter({DataSourceConfiguration.class})
    public class MybatisConfiguration extends MybatisAutoConfiguration {
        
        public MybatisConfiguration(MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
            super(properties, interceptorsProvider, resourceLoader, databaseIdProvider, configurationCustomizersProvider);
        }
    
        @Resource(name = "masterDatasource")
        private DataSource masterDataSource;
        @Resource(name = "slaveDatasource")
        private DataSource slaveDataSource;
    
        @Bean(name = "multipleDataSource")
        public MultipleDataSource multipleDataSource(){
            Map<Object, Object> targetDataSources = new HashMap<Object, Object>(2);
            targetDataSources.put(DataSourceContextHolder.DbType.MASTER,masterDataSource);
            targetDataSources.put(DataSourceContextHolder.DbType.SLAVE,slaveDataSource);
            MultipleDataSource multipleDataSource = new MultipleDataSource();
            multipleDataSource.setTargetDataSources(targetDataSources);
            multipleDataSource.setDefaultTargetDataSource(masterDataSource);
            return multipleDataSource;
        }
    
        @Bean(name = "sqlSessionFactory")
        public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
            return super.sqlSessionFactory(multipleDataSource());
        }
    }

到此,所有设置完成,可以用了:


image.png
上一篇 下一篇

猜你喜欢

热点阅读