springboot+druid+mybatis多数据源,干货,直接用

干货,复制下来直接用,亲测

配置文件


#master
spring.datasource.master.url=jdbc:mysql://127.0.0.1:3306/anyikongku?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true&autoReconnect=true&allowPublicKeyRetrieval=true
spring.datasource.master.username=root
spring.datasource.master.password=sql
spring.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.master.type=com.alibaba.druid.pool.DruidDataSource

spring.datasource.master.initialSize=5
spring.datasource.master.minIdle=5
spring.datasource.master.maxActive=20
spring.datasource.master.maxWait=60000
spring.datasource.master.timeBetweenEvictionRunsMillis=60000
spring.datasource.master.minEvictableIdleTimeMillis=300000
spring.datasource.master.validationQuery=SELECT 1 FROM DUAL
spring.datasource.master.testWhileIdle=true
spring.datasource.master.testOnBorrow=false
spring.datasource.master.testOnReturn=false
spring.datasource.master.poolPreparedStatements=true
spring.datasource.master.maxPoolPreparedStatementPerConnectionSize=20
#spring.datasource.filters=stat,wall,log4j
spring.datasource.master.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000


#slave
spring.datasource.slave.url=jdbc:mysql://127.0.0.1:3306/anyikongku_escape1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true&autoReconnect=true&allowPublicKeyRetrieval=true
spring.datasource.slave.username=root
spring.datasource.slave.password=sql
spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource

spring.datasource.slave.initialSize=5
spring.datasource.slave.minIdle=5
spring.datasource.slave.maxActive=20
spring.datasource.slave.maxWait=60000
spring.datasource.slave.timeBetweenEvictionRunsMillis=60000
spring.datasource.slave.minEvictableIdleTimeMillis=300000
spring.datasource.slave.validationQuery=SELECT 1 FROM DUAL
spring.datasource.slave.testWhileIdle=true
spring.datasource.slave.testOnBorrow=false
spring.datasource.slave.testOnReturn=false
spring.datasource.slave.poolPreparedStatements=true
spring.datasource.slave.maxPoolPreparedStatementPerConnectionSize=20
#spring.datasource.filters=stat,wall,log4j
spring.datasource.slave.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

数据源配置

package com.boot.springbootmvc.config.druid;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
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.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class DataSourceConfig {

	 @Primary
	@Bean(name = "first")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource first() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "second")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource second() {
        return DruidDataSourceBuilder.create().build();
    }
    
    @Bean(name = "third")
    @ConfigurationProperties(prefix = "spring.datasource.slave1")
    public DataSource third() {
        return DruidDataSourceBuilder.create().build();
    }
    

    @Bean(name = "dynamicRoutingDataSource")
    public DataSource dynamicRoutingDataSource(){
        DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource();

        Map<Object, Object> dataSourceMap = new HashMap<Object, Object>(3);

        dataSourceMap.put(DataSourceKey.MASTER, first());

        dataSourceMap.put(DataSourceKey.RADIUS, second());
        
        dataSourceMap.put(DataSourceKey.DHCP, third());

        
        dynamicRoutingDataSource.setTargetDataSources(dataSourceMap);
        
        DynamicDataSourceHolder.dataSourceKeys.addAll(dataSourceMap.keySet());

        return dynamicRoutingDataSource;
    }


    @Bean(name="sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactorys() throws Exception {
        log.info("--------------------  sqlSessionFactory init ---------------------");
        try {
            SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
            sessionFactoryBean.setDataSource(dynamicRoutingDataSource());
            // 读取配置
            sessionFactoryBean.setTypeAliasesPackage("com.boot.springbootmvc.entity");

            //设置mapper.xml文件所在位置
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml");
            sessionFactoryBean.setMapperLocations(resources);
            return sessionFactoryBean.getObject();
        } catch (IOException e) {
        	log.error("mybatis resolver mapper*xml is error", e);
            return null;
        } catch (Exception e) {
        	log.error("mybatis sqlSessionFactoryBean create error", e);
            return null;
        }
    }
}

 常量配置

package com.boot.springbootmvc.config.druid;

public class DataSourceKey {

	 public static final String MASTER = "anyi";
	 public static final String RADIUS = "radius";
	 public static final String DHCP = "dhcp";
}

配置切面动态切换

package com.boot.springbootmvc.config.druid;

import java.lang.reflect.Method;

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.annotation.Order;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Aspect
@Component
@Order(0)
public class DynamicDataSourceAspect {
	
	
	@Pointcut("execution(* com.boot.springbootmvc.dao.*.*(..))")
    public void dataSourcePointcut(){

    }

    @Before("dataSourcePointcut()")
    public void before(JoinPoint joinPoint) {
        Object target = joinPoint.getTarget();
        String method = joinPoint.getSignature().getName();
        Class<?>[] clazz = target.getClass().getInterfaces();
        Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
        try {
            Method m = clazz[0].getMethod(method, parameterTypes);
            if (clazz[0].isAnnotationPresent(TargetDataSource.class)) {
                TargetDataSource source = clazz[0].getAnnotation(TargetDataSource.class);
                DynamicDataSourceHolder.removeDataSourceRouterKey();
                DynamicDataSourceHolder.setDataSourceRouterKey(source.value());
            } else if (m != null && m.isAnnotationPresent(TargetDataSource.class)) { //如果方法上存在切换数据源的注解,则根据注解内容进行数据源切换
                TargetDataSource source = m.getAnnotation(TargetDataSource.class);
                DynamicDataSourceHolder.removeDataSourceRouterKey();
                DynamicDataSourceHolder.setDataSourceRouterKey(source.value());
                log.info(String.format("class[%s],method[%s],使用数据源[%s]", clazz[0].getName(), m.getName(),
                        DynamicDataSourceHolder.getDataSourceRouterKey()));
            } else {
                DynamicDataSourceHolder.removeDataSourceRouterKey();
                DynamicDataSourceHolder.setDataSourceRouterKey(DataSourceKey.MASTER);
                log.debug("switch datasource fail,use default");
            }
        } catch (Exception e) {
        	log.error("current thread " + Thread.currentThread().getName() + " add data to ThreadLocal error", e);
        }
    }

    @After("dataSourcePointcut()")
    public void after(JoinPoint joinPoint){
        DynamicDataSourceHolder.removeDataSourceRouterKey();
    }
}
package com.boot.springbootmvc.config.druid;

import java.util.ArrayList;
import java.util.List;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DynamicDataSourceHolder {

	/**
     * 存储已经注册的数据源的key
     */
    public static final List<Object> dataSourceKeys = new ArrayList<>();

    /**
     * 线程级别的私有变量
     */
    private static final ThreadLocal<String> HOLDER = new ThreadLocal<>();

    public static String getDataSourceRouterKey () {
    	String db=HOLDER.get();
    	if (db == null) {
            db = DataSourceKey.MASTER;
            // 默认是读写库
        }
        return db;
    }

    public static void setDataSourceRouterKey (String dataSourceRouterKey) {
        log.info("切换至{}数据源", dataSourceRouterKey);
        HOLDER.set(dataSourceRouterKey);
    }

    /**
     * 设置数据源之前一定要先移除
     */
    public static void removeDataSourceRouterKey () {
        HOLDER.remove();
    }

    /**
     * 判断指定DataSrouce当前是否存在
     *
     * @param dataSourceId
     * @return
     */
    public static boolean containsDataSource(String dataSourceId){
        return dataSourceKeys.contains(dataSourceId);
    }
}
package com.boot.springbootmvc.config.druid;

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

public class DynamicRoutingDataSource extends AbstractRoutingDataSource{
	@Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceHolder.getDataSourceRouterKey();
    }
}

 

package com.boot.springbootmvc.config.druid;

import java.lang.annotation.*;


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

	String value() default DataSourceKey.MASTER;
}

 mapper层

	@TargetDataSource(DataSourceKey.RADIUS)
	public Map<String, Object> getSlave();
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot是一种用于构建Java应用程序的框架,而Druid是一种开源的Java数据库连接池。MyBatis Plus是MyBatis的增强工具,可以简化数据库操作。将这三者整合在一起,可以提高开发效率和代码的易读性。 首先,我们需要在项目的pom.xml文件中添加引用依赖。可以通过Maven或Gradle来管理依赖项。在pom.xml中添加Spring BootDruidMyBatis Plus的相关依赖。 接下来,在application.yml或application.properties文件中配置数据库连接信息和Druid的相关配置。包括数据库的URL、用户名、密码以及Druid的一些监控和性能统计配置。 然后,创建一个DataSourceConfig类,用于配置Druid数据源,并使用@Configuration和@Bean注解将它声明为一个Bean。在该类中,可以设置连接池的一些属性,例如最小连接数、最大连接数、初始连接数等。 接着,创建一个MyBatisConfig类,用于配置MyBatis Plus。在该类中,可以配置MyBatis的类型别名、Mapper扫描路径和拦截器等。 最后,创建一个启动类,并使用@SpringBootApplication注解将其声明为Spring Boot应用程序的入口。在启动类中,可以使用@MapperScan注解指定MyBatis的Mapper接口所在的包路径,并在main方法中调用SpringApplication的run方法来启动应用程序。 通过以上步骤,我们就完成了Spring BootDruidMyBatis Plus的整合。现在可以在项目中编写Mapper接口和对应的XML文件,用于定义数据库的增删改查操作。并使用@Service或@Repository注解将Mapper接口声明为Spring组件,从而可以在其他地方直接使用@Autowired注解进行自动注入。 除此之外,还可以利用MyBatis Plus的一些特性,如自动生成代码、分页查询、多数据源配置等,进一步提高开发效率。 总结起来,Spring BootDruidMyBatis Plus的整合可以简化数据库操作,并提供了一些方便的特性和工具,让开发变得更加高效和简单。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-独孤求败-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值