MyBatis数据源的配置

  1、创建一个数据源配置文件

// 假设该文件名称为datasource.properties
# druid setting (主库配置) jdbcm.type=com.alibaba.druid.pool.DruidDataSource jdbcm.driverClassName=com.mysql.jdbc.Driver jdbcm.url=jdbc:mysql://ip:port/database_name?useUnicode=true
&characterEncoding=UTF-8&allowMultiQueries=true jdbcm.username=xxx jdbcm.password=xxxx

# druid setting (从库配置)
jdbcs.type=com.alibaba.druid.pool.DruidDataSource
jdbcs.driverClassName=com.mysql.jdbc.Driver
jdbcs.url=jdbc:mysql://ip:port/database_name?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
jdbcs.username=xxx
jdbcs.password=xxxx

  2、创建一个数据源配置类

@Configuration
@PropertySource("classpath:datasource_prod.properties") @MapperScan(basePackages="xxx") // 根据实际的业务代码路径来配置 @Profile("prod") // 根据bootstrap.yml的active配置项来确定 public class MyBatisBaseProdConfig implements EnvironmentAware { private Environment env; @Override public void setEnvironment(final Environment environment) { this.env = environment; } /** * description:创建数据源(主库) * @return DataSource对象 */ @Bean public DataSource majorDbDataSource() throws Exception { StandardPBEStringEncryptor spe = new StandardPBEStringEncryptor(); spe.setPassword(env.getProperty("jasypt.encryptor.password")); Properties props = new Properties(); props.put("url", env.getProperty("jdbcm.url")); props.put("username", spe.decrypt(env.getProperty("jdbcm.username"))); props.put("password", spe.decrypt(env.getProperty("jdbcm.password"))); this.setCommonJDBCProperties(props); return DruidDataSourceFactory.createDataSource(props); }
    /**
     * description:创建数据源(从库)
     * @return DataSource对象
     */
    @Bean
    public DataSource secondaryDbDataSource() throws Exception {
        StandardPBEStringEncryptor spe = new StandardPBEStringEncryptor();
        spe.setPassword(env.getProperty("jasypt.encryptor.password"));
        Properties props = new Properties();
        props.put("url", env.getProperty("jdbcs.url"));
        props.put("username", spe.decrypt(env.getProperty("jdbcs.username")));
        props.put("password", spe.decrypt(env.getProperty("jdbcs.password")));
        this.setCommonJDBCProperties(props);
        return DruidDataSourceFactory.createDataSource(props);
    }
   /**
    * 设置动态数据源
    * @param myTestDb2DataSource
    * @return DynamicDataSource对象
    */
    @Bean
    @Primary
    public DynamicDataSource dataSource(@Qualifier("majorDbDataSource") DataSource majorDbDataSource, 
                        @Qualifier("secondaryDbDataSource") DataSource secondaryDbDataSource) { Map
<Object, Object> targetDataSources = new HashMap<>(16); targetDataSources.put("major", majorDbDataSource);
targetDtatSources.put("secondary", secondaryDbDataSource); DynamicDataSource dataSource
= new DynamicDataSource(); dataSource.setTargetDataSources(targetDataSources); // 设置默认数据源 dataSource.setDefaultTargetDataSource(majorDbDataSource); return dataSource; } /** * 设置xml路径 **/ @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactoryBean(DynamicDataSource ds) { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(ds); ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { bean.setMapperLocations(resolver.getResources("classpath:*.xml")); // 根据实际情况来设置xml路径 return bean.getObject(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } /** * 配置事务管理器 */ @Bean public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception { return new DataSourceTransactionManager(dataSource); } /** * 设置共用的jdbc属性 * @param props */ private void setCommonJDBCProperties(Properties props) { props.put("initialSize", env.getProperty("jdbc.initialSize")); props.put("minIdle", env.getProperty("jdbc.minIdle")); props.put("maxActive", env.getProperty("jdbc.maxActive")); props.put("maxWait", env.getProperty("jdbc.maxWait")); props.put("validationQuery", env.getProperty("jdbc.validationQuery")); props.put("testOnBorrow", env.getProperty("jdbc.testOnBorrow")); props.put("testOnReturn", env.getProperty("jdbc.testOnReturn")); props.put("testWhileIdle", env.getProperty("jdbc.testWhileIdle")); props.put("timeBetweenEvictionRunsMillis", env.getProperty("jdbc.timeBetweenEvictionRunsMillis")); props.put("minEvictableIdleTimeMillis", env.getProperty("jdbc.minEvictableIdleTimeMillis")); props.put("removeAbandoned", env.getProperty("jdbc.removeAbandoned")); props.put("removeAbandonedTimeout", env.getProperty("jdbc.removeAbandonedTimeout")); props.put("logAbandoned", env.getProperty("jdbc.logAbandoned")); props.put("poolPreparedStatements", env.getProperty("jdbc.poolPreparedStatements")); props.put("maxPoolPreparedStatementPerConnectionSize", env.getProperty("jdbc.maxPoolPreparedStatementPerConnectionSize")); props.put("filters", env.getProperty("jdbc.filters")); } }

  3、创建一个数据源上下文保存类

public class DatabaseContextHolder {
    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    public static String getDatabaseType(){
        return CONTEXT_HOLDER.get();
    }

    public static void setDatabaseType(String type) {
        CONTEXT_HOLDER.set(type);
    }
    
    public static void clear() {
        CONTEXT_HOLDER.remove();
    }

  4、创建一个动态数据类

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DatabaseContextHolder.getDatabaseType();
    }
}

  5、创建一个AOP类,实现动态切换数据源

@Aspect
@Component
@Order(1)
public class DataSourceAspect {
    
    /**
     * 对业务层方法前切换数据源
     * @param point 切点
     */
    @Before("execution(*..service..*.*(..))") // 根据实际情况进行调整
    public void setDataSourceKey(JoinPoint point){
        if(point.getTarget().getClass().equals(XXClassImpl.class)){
        DatabaseContextHolder.setDatabaseType("secondary");
        } else {     
        DatabaseContextHolder.setDatabaseType("major");
        }
    }
 
    /**
     * 在业务层方法之后执行
     * @param point 切点
     */
    @After("execution(*..service..*.*(..))")  // 根据实际情况进行调整
    public void after(JoinPoint point){
        DatabaseContextHolder.clear();
    }
}

 

posted @ 2020-06-02 09:50  晒太阳的兔子很忙  阅读(701)  评论(0编辑  收藏  举报