POM依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>2.1.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
</dependencies>
DataSourceEnum:
package com.ck.mapping.common.datasource;
public enum DataSourceEnum {
dc_mapping_metadata_db("dc_mapping_metadata_db"),hive("hive");
private String value;
DataSourceEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
DataSource:
package com.ck.mapping.common.datasource;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
DataSourceEnum value() default DataSourceEnum.dc_mapping_metadata_db;
}
DataSourceAspect:
package com.ck.mapping.common.datasource;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Slf4j
@Aspect
@Order(-1) // 这是为了保证AOP在事务注解之前生效,Order的值越小,优先级越高
public class DataSourceAspect {
@Pointcut("execution(* com.ck.mapping.mapper..*.*(..))")
private void dcMappingMetadataDbAspect() {
}
/**
* 切换到dcMappingMetadataDbAspect 数据源
*/
@Before("dcMappingMetadataDbAspect()")
public void dcMappingMetadataDb() {
// 切换到 dcMappingMetadataDbAspect 数据源..
DataSourceContextHolder.setDbType(DataSourceEnum.dc_mapping_metadata_db);
}
@Pointcut("execution(* com.ck.mapping.mapper2..*.*(..))")
private void hiveDbAspect() {
}
@Before("hiveDbAspect()")
public void hiveDb() {
// 切换到hive数据源..
DataSourceContextHolder.setDbType(DataSourceEnum.hive);
}
@After("dcMappingMetadataDbAspect() || hiveDbAspect()")
public void doAfter(){
DataSourceContextHolder.clearDbType();
}
}
DataSourceContextHolder:
package com.ck.mapping.common.datasource;
public class DataSourceContextHolder {
private static final ThreadLocal<Object> contextHolder = new ThreadLocal<>();
/**
* 设置数据源
*
* @param dbTypeEnum
*/
public static void setDbType(DataSourceEnum dbTypeEnum) {
contextHolder.set(dbTypeEnum.getValue());
}
/**
* 取得当前数据源
*
* @return
*/
public static String getDbType() {
return String.valueOf(contextHolder.get());
}
/**
* 清除上下文数据
*/
public static void clearDbType() {
contextHolder.remove();
}
}
DynamicDataSource:
package com.ck.mapping.common.datasource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 取得当前使用哪个数据源
*
* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDbType();
}
}
DruidConfiguration:
package com.ck.mapping.common.datasource;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
@Configuration
public class DruidConfiguration {
@Bean
public ServletRegistrationBean<StatViewServlet> startViewServlet(){
ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<StatViewServlet>(new StatViewServlet(),"/druid/*");
// IP白名单
// servletRegistrationBean.addInitParameter("allow","127.0.0.1");
// IP黑名单(共同存在时,deny优先于allow)
// servletRegistrationBean.addInitParameter("deny","127.0.0.1");
//控制台管理用户
servletRegistrationBean.addInitParameter("loginUsername","admin");
servletRegistrationBean.addInitParameter("loginPassword","admin");
//是否能够重置数据
servletRegistrationBean.addInitParameter("resetEnable","false");
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean<WebStatFilter> statFilter(){
FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<WebStatFilter>(new WebStatFilter());
//添加过滤规则
filterRegistrationBean.addUrlPatterns("/*");
//忽略过滤的格式
filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
MyBatiesPlusConfiguration:
package com.ck.mapping.common.datasource;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
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.context.annotation.Profile;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.ISqlInjector;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
@Configuration
@MapperScan("com.ck.mapping.mapper")
public class MyBatiesPlusConfiguration {
/**
* 分页插件,自动识别数据库类型 多租户,请参考官网【插件扩展】
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 开启 PageHelper 的支持
paginationInterceptor.setLocalPage(true);
return paginationInterceptor;
}
/**
* SQL执行效率插件
*/
@Bean
@Profile({"dev", "qa"}) // 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(1000);
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
@Bean(name = "dcMappingMetadataDb")
@ConfigurationProperties(prefix = "spring.datasource.druid.mapping-metadata")
public DataSource dcMappingMetadataDb() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "hiveDb")
@ConfigurationProperties(prefix = "spring.datasource.druid.hive")
public DataSource hiveDb() {
return DruidDataSourceBuilder.create().build();
}
/**
* 动态数据源配置
* @return
*/
@Bean
@Primary
public DataSource multipleDataSource(@Qualifier("dcMappingMetadataDb") DataSource dcMappingMetadataDb, @Qualifier("hiveDb") DataSource hiveDb) {
DynamicDataSource multipleDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceEnum.dc_mapping_metadata_db.getValue(), dcMappingMetadataDb);
targetDataSources.put(DataSourceEnum.hive.getValue(), hiveDb);
// 添加数据源
multipleDataSource.setTargetDataSources(targetDataSources);
// 设置默认数据源
multipleDataSource.setDefaultTargetDataSource(dcMappingMetadataDb);
return multipleDataSource;
}
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
/**
* 逻辑删除插件
* @return
*/
@Bean
public GlobalConfiguration globalConfig() {
GlobalConfiguration globalConfig = new GlobalConfiguration(new LogicSqlInjector());
globalConfig.setLogicDeleteValue("1");
globalConfig.setLogicNotDeleteValue("0");
globalConfig.setIdType(2);
return globalConfig;
}
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
// TODO
sqlSessionFactory.setDataSource(multipleDataSource(dcMappingMetadataDb(), hiveDb()));
// 开启XML
sqlSessionFactory.setMapperLocations(new
PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/*/*Mapper.xml"));
MybatisConfiguration configuration = new MybatisConfiguration();
// 开启XML
configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
configuration.setMapUnderscoreToCamelCase(false);
configuration.setCacheEnabled(false);
sqlSessionFactory.setConfiguration(configuration);
sqlSessionFactory.setPlugins(new Interceptor[]{ // PerformanceInterceptor(),OptimisticLockerInterceptor()
paginationInterceptor() // 添加分页功能
});
//自定义扩展策略
sqlSessionFactory.setGlobalConfig(globalConfig());
return sqlSessionFactory.getObject();
}
}