返回顶部
首页 > 资讯 > 后端开发 > JAVA >JAVA:Springboot动态装配Druid多数据源
  • 557
分享到

JAVA:Springboot动态装配Druid多数据源

springbootjavadruid 2023-09-29 06:09:05 557人浏览 薄情痞子
摘要

1、简介 最近打算搭建一个鉴权中心服务,采用SpringBoot+Fastmybatis装配Druid,考虑后续拓展采用Druid多数据源配置,以一个数据源为主,多个动态数据源为辅的结构。除了数据库,

1、简介

最近打算搭建一个鉴权中心服务,采用SpringBoot+Fastmybatis装配Druid,考虑后续拓展采用Druid多数据源配置,以一个数据源为主,多个动态数据源为辅的结构。除了数据库,后续会结合shiro安全框架来搭建。

2、引用

在pom.xml添加框架springboot +FastMybatis + Druid相关Maven引用。

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-WEB</artifactId></dependency><dependency>    <groupId>net.oschina.durcframework</groupId>    <artifactId>fastmybatis-spring-boot-starter</artifactId>    <version>${fastmybatis.version}</version></dependency><dependency>    <groupId>com.alibaba</groupId>    <artifactId>druid-spring-boot-starter</artifactId>    <version>${druid.version}</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-core</artifactId>    <version>${shiro.version}</version></dependency><dependency>    <groupId>org.apache.shiro</groupId>    <artifactId>shiro-spring</artifactId>    <version>${shiro.version}</version></dependency>

3、数据源队列

我们采用的是一个数据源为主,多个动态数据源为辅的结构,在后续添加新的数据源,我们只要调整新数据源配置就可以了,不用再改原来结构。所以我们要有自己的数据源队列来存储动态的数据源。

public class DynamicContextUtils {       private static final ThreadLocal<Deque<String>> CONTEXT = new ThreadLocal() {        @Override        protected Object initialValue() {            return new ArrayDeque();        }    };        public static String peek() {        return CONTEXT.get().peek();    }        public static void push(String dataSource) {        CONTEXT.get().push(dataSource);    }        public static void poll() {        Deque<String> deque = CONTEXT.get();        deque.poll();        if (deque.isEmpty()) {            CONTEXT.remove();        }    }}

4、数据源切面

首先我们要添加自己的annotion,并可以切面中可以拦截并加载动态数据源。

@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface DataSource {    String value() default "";}

现在我们在切面中拦截自己添加的annotion,然后通过@Aspect添加到我们定义的数据源队列中。

@Aspect@Component@Order(Ordered.HIGHEST_PRECEDENCE)public class DataSourceAspect {    protected Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);    @Pointcut("@annotation(com.xhl.lk.auth2.datasource.annotation.DataSource)" +            "|| @within(com.xhl.lk.auth2.datasource.annotation.DataSource)")    public  void dataSourcePointCut(){    }    @Around("dataSourcePointCut()")    public  Object around(@NotNull ProceedingJoinPoint point) throws Throwable{        MethodSignature signature = (MethodSignature) point.getSignature();        Class targetClass = point.getTarget().getClass();        Method method = signature.getMethod();        DataSource targetDataSource = (DataSource) targetClass.getAnnotation(DataSource.class);        DataSource methodDataSource = method.getAnnotation(DataSource.class);        if(Objects.nonNull(targetDataSource) || Objects.nonNull(methodDataSource)){            String value = Objects.nonNull(methodDataSource) ? methodDataSource.value() : targetDataSource.value();            DynamicContextUtils.push(value);            logger.debug("set datasource is {}", value);        }        try{            return point.proceed();        }finally {            DynamicContextUtils.poll();            logger.info("clean datasource");        }    }}

5、数据源属性

添加Druid主数据源和动态数据源参数映射类,以便可以通过映射来调整和链接数据库

@Datapublic class DataSourceProperty {    private String driverClassName;    private String url;    private String username;    private String passWord;        private int initialSize = 2;    private int maxActive = 10;    private int minIdle = -1;    private long maxWait = 60 * 1000L;    private long timeBetweenEvictionRunsMillis = 60 * 1000L;    private long minEvictableIdleTimeMillis = 1000L * 60L * 30L;    private long maxEvictableIdleTimeMillis = 1000L * 60L * 60L * 7;    private String validationQuery = "select 1";    private int validationQueryTimeout = -1;    private boolean testOnBorrow = false;    private boolean testOnReturn = false;    private boolean testWhileIdle = true;    private boolean poolPreparedStatements = false;    private int maxOpenPreparedStatements = -1;    private boolean sharePreparedStatements = false;    private String filters = "stat,wall";}

动态数据源属性以当前主数据源为主,从队列中获取。通过@ConfigurationProperties来标识动态数据源前缀。

@Data@ConfigurationProperties(prefix = "dynamic")public class DynamicDataSourceProperty {    private Map<String, DataSourceProperty> datasource = new LinkedHashMap<>();}

我们在配置文件application.yml定义多个数据源配置:

spring:    datasource:        type: com.alibaba.druid.pool.DruidDataSource        druid:            driver-class-name: com.Mysql.cj.jdbc.Driver            url: jdbc:mysql://192.168.254.128:3306/sys_xhl?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai            username: shdxhl            password: shdxhl            initial-size: 10            max-active: 100            min-idle: 10            max-wait: 60000            pool-prepared-statements: true            max-pool-prepared-statement-per-connection-size: 20            time-between-eviction-runs-millis: 60000            min-evictable-idle-time-millis: 300000            #oracle需要打开注释            #validation-query: SELECT 1 FROM DUAL            #spring.datasource.druid.test-on-borrow=true            #spring.datasource.druid.test-while-idle=true            test-while-idle: true            test-on-borrow: true            test-on-return: false            stat-view-servlet:                enabled: true                url-pattern: /druid/*                #login-username: admin                #login-password: admin            filter:                stat:                    log-slow-sql: true                    slow-sql-millis: 1000                    merge-sql: false                wall:                    config:                        multi-statement-allow: true##多数据源的配置dynamic:  datasource:    slave1:        driver-class-name: com.mysql.cj.jdbc.Driver        url: jdbc:mysql://192.168.254.128:3306/blog_weike?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai        username: blog        password: wiloveyou#    slave2:#      driver-class-name: org.postgresql.Driver#      url: jdbc:postgresql://localhost:5432/renren_security#      username: renren#      password: 123456

6、Config初始化

在@Configuration中实现主数据源和多个动态数据源数据链接初始化,同时通过继承AbstractRoutingDataSource来实现动态数据源切换。

//通过重载determineCurrentLookupKey 来获取切换的数据源Key。public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {        return DynamicContextUtils.peek();    }}

创建一个Dynamic数据源的Factory来实现动态数据源参数映射和Druid数据源初始化:

public class DynamicDataSourceFactory {    protected static Logger logger = LoggerFactory.getLogger(DynamicDataSourceFactory.class);    //build动态数据源,初始化    public static DruidDataSource buildDruidDataSource(DataSourceProperty properties) {        DruidDataSource druidDataSource = new DruidDataSource();        druidDataSource.setDriverClassName(properties.getDriverClassName());        druidDataSource.setUrl(properties.getUrl());        druidDataSource.setUsername(properties.getUsername());        druidDataSource.setPassword(properties.getPassword());        druidDataSource.setInitialSize(properties.getInitialSize());        druidDataSource.setMaxActive(properties.getMaxActive());        druidDataSource.setMinIdle(properties.getMinIdle());        druidDataSource.setMaxWait(properties.getMaxWait());        druidDataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());        druidDataSource.setMinEvictableIdleTimeMillis(properties.getMinEvictableIdleTimeMillis());        druidDataSource.setMaxEvictableIdleTimeMillis(properties.getMaxEvictableIdleTimeMillis());        druidDataSource.setValidationQuery(properties.getValidationQuery());        druidDataSource.setValidationQueryTimeout(properties.getValidationQueryTimeout());        druidDataSource.setTestOnBorrow(properties.isTestOnBorrow());        druidDataSource.setTestOnReturn(properties.isTestOnReturn());        druidDataSource.setPoolPreparedStatements(properties.isPoolPreparedStatements());        druidDataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());        druidDataSource.setSharePreparedStatements(properties.issharePreparedStatements());        try {            druidDataSource.setFilters(properties.getFilters());            druidDataSource.init();        } catch (SQLException e) {            logger.error("DynamicDataSourceFactory is error:" + e.toString());        }        return druidDataSource;    }}

最后我们在@Configuration添加多个数据源对象bean实例:

@Configuration@EnableConfigurationProperties(DynamicDataSourceProperty.class)public class DynamicDataSourceConfig {    @Autowired    private DynamicDataSourceProperty properties;    @Bean    @ConfigurationProperties(prefix = "spring.datasource.druid")    public DataSourceProperty dataSourceProperty() {        return new DataSourceProperty();    }    @Bean    public DynamicDataSource dynamicDataSource(DataSourceProperty dataSourceProperty) {        DynamicDataSource dynamicDataSource = new DynamicDataSource();        dynamicDataSource.setTargetDataSources(getDynamicDataSource());        //默认数据源        DruidDataSource defaultDataSource = DynamicDataSourceFactory.buildDruidDataSource(dataSourceProperty);        dynamicDataSource.setDefaultTargetDataSource(defaultDataSource);        return dynamicDataSource;    }    private Map<Object, Object> getDynamicDataSource(){        Map<String, DataSourceProperty> dataSourcePropertyMap = properties.getDatasource();        Map<Object, Object> targetDataSources = new ConcurrentHashMap<>(dataSourcePropertyMap.size());        dataSourcePropertyMap.forEach((k, v) -> {            DruidDataSource druidDataSource = DynamicDataSourceFactory.buildDruidDataSource(v);            targetDataSources.put(k, druidDataSource);        });        return targetDataSources;    }}

7、验证

最后我们可以很轻松的验证当前Druid多数据源配置是否生效,通过访问Http://localhost:8080/lk-auth/druid/的地址,可以很清楚的看到数据库执行语句和数据源的各种指标。代码链接:https://gitee.com/lhdxhl/lk-auth.git

在这里插入图片描述

来源地址:https://blog.csdn.net/lishangke/article/details/131298271

--结束END--

本文标题: JAVA:Springboot动态装配Druid多数据源

本文链接: https://lsjlt.com/news/421098.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • JAVA:Springboot动态装配Druid多数据源
    1、简介 最近打算搭建一个鉴权中心服务,采用springboot+FastMybatis装配Druid,考虑后续拓展采用Druid多数据源配置,以一个数据源为主,多个动态数据源为辅的结构。除了数据库,...
    99+
    2023-09-29
    spring boot java druid
  • druid多数据源配置+Datasurce动态切换方式
    目录druid多数据源配置+Datasurce动态切换AbstractRoutingDataSource 数据源动态切换例子配置多数据源并实现Druid自动切换配置yml文件主数据源...
    99+
    2024-04-02
  • 使用springboot+druid双数据源动态配置操作
    目录一、yml配置二、动态切换数据源配置文件1.数据源db12.数据源db2三、多数据源的mapper包最好是分开四、代码中调用总结进行动态切换,需要在类里面配置,顺便解决mybat...
    99+
    2024-04-02
  • springboot中如何利用mybatis+druid配置动态数据源
    这篇“springboot中如何利用mybatis+druid配置动态数据源”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“s...
    99+
    2023-06-08
  • springboot整合druid及多数据源配置
    前言 本篇主要分两部分 ①springboot整合druid的代码配置,以及druid的监控页面演示;②对实际场景中多数据源的配置使用进行讲解。 一、springboot整合druid的演示demo 可以用idea快速生成一个可运行的dem...
    99+
    2023-10-24
    spring boot java spring
  • springboot mybatis druid配置多数据源教程
    目录1、项目代码结构2、导入基本依赖3、配置多数据源4、配置类5、启动类6、测试使用的表7、测试表对应的实体类8、持久层:dao层接口1、项目代码结构 2、导入基本依赖 记得需要导...
    99+
    2024-04-02
  • SpringBoot使用druid配置多数据源问题
    目录一、背景二、版本介绍三、项目结构四、maven依赖 五、yaml配置文件六、数据源配置文件七、启动类配置八、druid管理页面总结一、背景 使用spring boot配...
    99+
    2023-03-11
    SpringBoot配置多数据源 druid配置多数据源 druid多数据源
  • SpringBoot怎么使用druid配置多数据源
    这篇“SpringBoot怎么使用druid配置多数据源”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringBoot怎...
    99+
    2023-07-05
  • Druid数据源推荐配置
    Druid数据源推荐配置: 以下Druid数据源配置是本人整理的生产配置。 大家可以直接拷贝使用,注释非常完善。 spring: datasource: druid: url: ...
    99+
    2023-09-18
    mysql 数据库 java
  • springboot配置druid多数据源的示例代码
    目录1、配置多数据源所需要的jar2、配置多数据源所需要的工具类3、DataSourceType 枚举类4、DruidProperties druid 配置属性5、DruidConf...
    99+
    2024-04-02
  • 解决Druid动态数据源配置重复刷错误日志的问题
    Druid动态数据源配置 主要是继承AbstractRoutingDataSource再通过AOP来实现动态数据源切换. 下面给大家介绍Druid动态配置数据源重复刷错误日志问题,具...
    99+
    2024-04-02
  • springboot 中怎么配置DRUID数据源
    本篇文章为大家展示了springboot 中怎么配置DRUID数据源,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1.修改pom.xml<dependency>  &...
    99+
    2023-06-02
  • SpringBoot多数据源配置并通过注解实现动态切换数据源
    目录1. 环境准备1.1 数据库准备1.2 项目创建2. ThreadLocal类介绍3. AbstractRoutingDataSource类介绍4. 具体实现4.1 定义数据源枚...
    99+
    2022-11-13
    SpringBoot 动态切换数据源 SpringBoot 切换数据源
  • springboot配置多数据源并集成Druid和mybatis的操作
    可以是mysql,oracle等多种不同数据源 项目结构 注意:只有@Primary的数据源所控制的mapper文件加注解@Mapper,否则mybatis无法切换扫描;即本文中...
    99+
    2024-04-02
  • 详解Spring Boot整合Mybatis实现 Druid多数据源配置
    一、多数据源的应用场景目前,业界流行的数据操作框架是 Mybatis,那 Druid 是什么呢?Druid 是 Java 的数据库连接池组件。Druid 能够提供强大的监控和扩展功能。比如可以监控 SQL ,在监控业务可以查询慢查询 SQL...
    99+
    2023-05-31
    spring 多数据源 spring boo
  • 【Java】Spring Boot配置动态数据源
    SpringBoot配置动态数据源 一、动态多数据源的配置 1.1 创建动态数据源 通过实现Spring提供的AbstractRoutingDataSource类,可以实现自己的数据源选择逻辑,从而可...
    99+
    2023-09-15
    java spring boot 开发语言
  • BIRT怎么配置动态数据源
    小编今天带大家了解BIRT怎么配置动态数据源,文中知识点介绍的非常详细。觉得有帮助的朋友可以跟着小编一起浏览文章的内容,希望能够帮助更多想解决这个问题的朋友找到问题的答案,下面跟着小编一起深入学习“BIRT怎么配置动态数据源”的知识吧。BI...
    99+
    2023-06-03
  • Jasper如何配置动态数据源
    Jasper如何配置动态数据源,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Jasper 本身是不支持动态数据源的,能用的解决方式是通过 api 自定义数据源,...
    99+
    2023-06-03
  • 【Java多数据源实现教程】实现动态数据源、多数据源切换方式
    前言 本文为 【Java多数据源实现教程】 相关知识,由于自己最近在做导师的项目的时候需要使用这种技术,于是自学了相关技术原理与实现,并将其整理如下,具体包含:多数据源的典型使用场景(包含业务复杂场景、读写分离场景),多数据源实现原理及实...
    99+
    2023-08-16
    java mybatis spring
  • springboot + mybatis + druid + 多数据源的问题详解
    目录一. 简介 二. sql脚本三. 工程搭建3.1 目录结构图3.2 pom.xml文件3.3 application.yml 3.4 数据源配置类3.5 Co...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作