• Spring boot+MYSQL多数据源


    引入maven:

    com.alibaba

    druid

    1.1.22

    DataBase :
    package com.example.zhwj.config;

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface DataBase {

    String value() default "db1";
    

    }

    DatabaseContextHolder :
    package com.example.zhwj.config;

    public class DatabaseContextHolder {

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    //默认数据源
    public static final String DEFAULT_DS = "db1";
    
    public static void setDatabaseType(String type) {
    	contextHolder.set(type);
    }
    
    public static String getDatabaseType() {
    	return contextHolder.get();
    }
    
    public static void clearDataSource() {
    	contextHolder.remove();
    }
    

    }

    DataSourceAspect :
    package com.example.zhwj.config;

    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.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.core.Ordered;
    import org.springframework.stereotype.Component;

    import java.lang.reflect.Method;

    @Aspect
    @Component
    public class DataSourceAspect implements Ordered {

    @Pointcut("@annotation(DataBase)")//注意:这里的xxxx代表的是上面public @interface DataSource这个注解DataSource的包名
    public void dataSourcePointCut() {
    
    }
    
    @SuppressWarnings("rawtypes")
    @Before("dataSourcePointCut()")
    public void beforeSwitchDS(JoinPoint point){
    	//获得当前访问的class
    	Class<?> className = point.getTarget().getClass();
    	//获得访问的方法名
    	String methodName = point.getSignature().getName();
    	//得到方法的参数的类型
    	Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
    
    	String dataSource = DatabaseContextHolder.DEFAULT_DS;
    	try {
    		// 得到访问的方法对象
    		Method method = className.getMethod(methodName, argClass);
    
    		// 判断是否存在@DateBase注解
    		if (method.isAnnotationPresent(DataBase.class)) {
    			DataBase annotation = method.getAnnotation(DataBase.class);
    			// 取出注解中的数据源名
    			dataSource = annotation.value();
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	// 切换数据源
    	DatabaseContextHolder.setDatabaseType(dataSource);
    }
    
    
    @After("dataSourcePointCut()")
    public void afterSwitchDS(JoinPoint point){
    	DatabaseContextHolder.clearDataSource();
    }
    
    
    @Override
    public int getOrder() {
    	return 1;
    }
    

    }

    DruidConfig:
    package com.example.zhwj.config;

    import com.alibaba.druid.filter.Filter;
    import com.alibaba.druid.filter.stat.StatFilter;
    import com.alibaba.druid.pool.DruidDataSource;
    import com.alibaba.druid.support.http.StatViewServlet;
    import com.alibaba.druid.support.http.WebStatFilter;
    import com.google.common.collect.Lists;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    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 org.springframework.context.annotation.Primary;
    import org.springframework.core.env.Environment;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;

    import javax.sql.DataSource;
    import java.sql.SQLException;
    import java.util.HashMap;
    import java.util.Map;

    @Configuration
    public class DruidConfig {

    @Autowired
    private Environment env;
    
    @Primary
    @ConfigurationProperties(prefix="spring.datasource.db1")
    @Bean(name = "datasource1")
    public DataSource dataSourceDB1(Filter statFilter) throws SQLException{
    	DruidDataSource dataSource = new DruidDataSource();
    	dataSource.setProxyFilters(Lists.newArrayList(statFilter()));
    	return dataSource;
    }
    
    /**
     * @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
     * @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
     */
    @Bean(name = "dynamicDataSource")
    public DynamicDataSource dataSource(@Qualifier("datasource1") DataSource datasource1) {
    	Map<Object, Object> targetDataSources = new HashMap<>();
    	targetDataSources.put(DatabaseContextHolder.DEFAULT_DS, datasource1);
    	DynamicDataSource dataSource = new DynamicDataSource();
    	dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法
    	dataSource.setDefaultTargetDataSource(datasource1);// 默认的datasource设置为dataSourceDB1
    
    	return dataSource;
    }
    
    
    /**
     * 根据数据源创建SqlSessionFactory
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DynamicDataSource ds) throws Exception {
    	SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
    	fb.setDataSource(ds);// 指定数据源(这个必须有,否则报错)
    	// 下边两句仅仅用于*.xml文件,如果整个持久层操作不需要使用到xml文件的话(只用注解就可以搞定),则不加
    	fb.setTypeAliasesPackage("com.example.zhwj.model");// 指定基包
    	fb.setMapperLocations(
    	        new PathMatchingResourcePatternResolver().getResources("mapper/*.xml"));//
    	return fb.getObject();
    }
    
    /**
     * 配置事务管理器
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
    	return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean
    public Filter statFilter(){
    	StatFilter filter = new StatFilter();
    	filter.setSlowSqlMillis(5000);
    	filter.setLogSlowSql(true);
    	filter.setMergeSql(true);
    	return filter;
    }
    
    
    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
    	//org.springframework.boot.context.embedded.ServletRegistrationBean提供类的进行注册.
    	ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
    
    	//添加初始化参数:initParams
    	//白名单:
    	// servletRegistrationBean.addInitParameter("allow","127.0.0.1");
    	//IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page.
    	//servletRegistrationBean.addInitParameter("deny","192.168.1.73");
    	//登录查看信息的账号密码.
    	servletRegistrationBean.addInitParameter("loginUsername","admin");
    	servletRegistrationBean.addInitParameter("loginPassword","123456");
    	//在日志中打印执行慢的sql语句
    	servletRegistrationBean.addInitParameter("logSlowSql", "true");
    	//是否能够重置数据.
    	servletRegistrationBean.addInitParameter("resetEnable","false");
    
    	return servletRegistrationBean;
    }
    
    
    @Bean
    public FilterRegistrationBean druidStatFilter(){
    
    	FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    	filterRegistrationBean.setFilter(new WebStatFilter());
    	filterRegistrationBean.addUrlPatterns("/*");
    	//过滤文件类型
    	filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
    	//监控单个url调用的sql列表
    	filterRegistrationBean.addInitParameter("profileEnable", "true");
    	return filterRegistrationBean;
    }
    

    }

    DynamicDataSource :
    package com.example.zhwj.config;

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

    public class DynamicDataSource extends AbstractRoutingDataSource {

    /**
     * 动态数据源(需要继承AbstractRoutingDataSource)
     */
    @Override
    protected Object determineCurrentLookupKey() {
    	return DatabaseContextHolder.getDatabaseType();
    }
    

    }

    spring:
    datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    db1:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&useTimezone=true&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

    以上配置完成后,即可在你的serviceImpl中加入注解
    @DataBase(value = "db1")
    即可使用

  • 相关阅读:
    nginx设置屏蔽,可访问id的方法
    python实现rcp远程调用介绍
    0.0.0.0
    datetime 模块详解 -- 基本的日期和时间类型
    python函数——形参中的:*args和**kwargs
    时间加一天,一个小时得到新的时间
    good blog
    Python-第三方库requests详解
    python requests的content和text方法的区别
    MyEclipse使用总结——设置MyEclipse开发项目时使用的JDK
  • 原文地址:https://www.cnblogs.com/zzqcupidzhq/p/13969360.html
Copyright © 2020-2023  润新知