spring mysql 多数据源_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 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 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")

即可使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值