• Spring Boot HikariCP 一 ——集成多数据源


    其实这里介绍的东西主要是参考的另外一篇文章,数据库读写分离的。

    参考文章就把链接贴出来,里面有那位的代码,简单明了https://gitee.com/comven/dynamic-datasource-demo?spm=5176.100239.blogcont188540.13.iARYDh。

    这块内容前前后后总共写了三篇
    1. Spring Boot HikariCP 一 ——集成多数据源
    2. Spring Boot 动态切换数据源二——负载均衡
    3. Spring Boot 动态切换数据源三——动态获取配置文件中的配置信息
    4. 插件GitHubrhettpang/dynamic-datasource

    读写分离的功能我已经使用replication集成好了,因为我们需要单独设置每个数据源的链接属性,而且使用的还是Hikari数据源,所以又在网上找了两天,最终昨天晚上发现了这种方式。
    我这里说说自己集成的时候的一些注意点。

    配置文件:

    hikari:
    master:
    jdbc-url: jdbc:mysql://masterhost:3306/testdb?useUnicode=true&characterEncoding=utf8&useSSL=true&allowMultiQueries=true&verifyServerCertificate=false
    username: root
    password: root
    maximum-pool-size: 20
    pool-name: master
    connection-timeout: 30000
    idle-timeout: 600000
    max-lifetime: 1765000
    slave:
    jdbc-url: jdbc:mysql://slavehost:3306/testdb?useUnicode=true&characterEncoding=utf8&useSSL=true&allowMultiQueries=true&verifyServerCertificate=false
    username: root
    password: root
    maximum-pool-size: 80
    pool-name: slave
    connection-timeout: 30000
    idle-timeout: 600000
    max-lifetime: 1765000
    read-only: true


    我这里主要用到的是maximum-pool-size这个值,一般情况下读数据库(slave)总会比写(master)要多一些,而且往往是一个master多个slave。所以,maximum-pool-size这个值在master的设置小于slave比较高效。

    import com.zaxxer.hikari.HikariDataSource;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;

    /**
    * @author Created by pangkunkun on 2017/12/18.
    */
    @Component
    @ConfigurationProperties(prefix = "hikari")
    public class DBProperties {
    private HikariDataSource master;
    private HikariDataSource slave;

    public HikariDataSource getMaster() {
    return master;
    }

    public void setMaster(HikariDataSource master) {
    this.master = master;
    }

    public HikariDataSource getSlave() {
    return slave;
    }

    public void setSlave(HikariDataSource slave) {
    this.slave = slave;
    }
    }


    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.transaction.PlatformTransactionManager;

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

    /**
    * @author Created by pangkunkun on 2017/12/18.
    */
    @Configuration
    @EnableScheduling
    public class DataSourceConfig {

    @Autowired
    private DBProperties properties;

    @Bean(name = "dataSource")
    public DataSource dataSource() {
    //按照目标数据源名称和目标数据源对象的映射存放在Map中
    Map<Object, Object> targetDataSources = new HashMap<>();
    targetDataSources.put("master", properties.getMaster());
    targetDataSources.put("slave", properties.getSlave());
    //采用是想AbstractRoutingDataSource的对象包装多数据源
    DynamicDataSource dataSource = new DynamicDataSource();
    dataSource.setTargetDataSources(targetDataSources);
    //设置默认的数据源,当拿不到数据源时,使用此配置
    dataSource.setDefaultTargetDataSource(properties.getMaster());
    return dataSource;
    }

    @Bean
    public PlatformTransactionManager txManager() {
    return new DataSourceTransactionManager(dataSource());
    }
    }


    import com.easyar.cloud.cms.common.util.TargetDataSource;
    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.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;

    import java.lang.reflect.Method;

    /**
    * @author Created by pangkunkun on 2017/12/18.
    */
    @Component
    @Aspect
    public class DataSourceAspect {


    private final static Logger log= LoggerFactory.getLogger(DataSourceAspect.class);

    //切换放在mapper接口的方法上,所以这里要配置AOP切面的切入点
    @Pointcut("execution( * com.easyar.cloud.cms.dao.mapper.*.*(..))||execution( * com.easyar.cloud.cms.shiro.mapper.*.*(..))")
    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 (m != null && m.isAnnotationPresent(TargetDataSource.class)) {
    TargetDataSource data = m.getAnnotation(TargetDataSource.class);
    String dataSourceName = data.value();
    DynamicDataSourceHolder.putDataSource(dataSourceName);
    log.debug("current thread " + Thread.currentThread().getName() + " add " + dataSourceName + " to ThreadLocal");
    } else {
    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.removeDataSource();
    }

    }

    原文:https://blog.csdn.net/qq_35981283/article/details/78846892

  • 相关阅读:
    1096 Consecutive Factors (20分)
    js-实现省市区地址选择器三级联动
    js-面向对象编程基础
    js-滑块拼图登录验证
    js-promise以及async、await实现简易红绿灯
    js-前端分页效果的实现
    js-ajax方法详解以及封装
    js-jsonp跨域请求原理以及jsonp的封装
    js-实现常见的拖拽效果(表单滑块验证)
    js本地存储-localStorage和cookie详解以及区别
  • 原文地址:https://www.cnblogs.com/lykbk/p/sefsdfsdfsd2343243534.html
Copyright © 2020-2023  润新知