Spring框架下利用AbstractRoutingDataSource配置多数据源

Spring的AbstractRoutingDataSource多数据源切换 spring实现多数据源切换示例讲解多数据源切换的使用场景maven坐标数据库准备sql脚本`(两个库各一个user表)`数据库配置文件`jdbc.properties`实体数据模型mapper准备mapper接口`UserMapper`mapper配置文件`UserMapper.xml`切换数据源实现连接池名称枚举`DataSourceType`连接池主键名称存取对象`DynamicDataSo... 阅读详情

首先看Druid数据库多数据源Demo

Spring的多数据源支持---AbstractRoutingDataSource,AbstractRoutingDataSource定义了抽象的determineCurrentLookupKey方法,子类实现此方法,来确定要使用的数据源

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
	 protected DataSource determineTargetDataSource() {
		Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
		Object lookupKey = determineCurrentLookupKey();
		DataSource dataSource = this.resolvedDataSources.get(lookupKey);
		if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
			dataSource = this.resolvedDefaultDataSource;
		}
		if (dataSource == null) {
			throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
		}
		return dataSource;
	}

        // 确定当前要使用的数据源
        protected abstract Object determineCurrentLookupKey();
}

Druid 实现多数据源支持,核心是Overwrite AbstractRoutingDataSource 的 determineCurrentLookupKey 方法

  public class MultipleDataSource extends AbstractRoutingDataSource {
	public static final String DATA_SOURCE_A = "dataSourceTestA";  // A库
	public static final String DATA_SOURCE_B = "dataSourceTestB";  // B库

	private static final ThreadLocal<String> dataSourceKey = new ThreadLocal<String>();

	public static void setDataSourceKey(String dataSource) {
		dataSourceKey.set(dataSource);
	}

	@Override
	protected Object determineCurrentLookupKey() {
		return dataSourceKey.get();
	}

	public static void clear(){
		dataSourceKey.remove();
	}
}

AbstractRoutingDataSourceApplication实战:

DataSourceLeonProperties

package center.leon.oak.druid.abstract_routing_data_source.properties;

import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 13:56
 **/
@Data
@Component
@ConfigurationProperties(value = "spring.datasource.leon")
public class DataSourceLeonProperties {

    /**
     * 默认数据源
     */
    private DataSourceLeon defaultDataSourceLeon;
    /**
     * 数据源列表
     */
    private List<DataSourceLeon> dataSourceLeonList;


    /**
     * 自定义数据源
     */
    @Data
    @Accessors(chain = true)
    public static class DataSourceLeon {
        /**
         * 数据源自定义名称
         */
        private String dataSourceName;
        /**
         * 数据源驱动
         */
        private String driverClassName;
        /**
         * 数据源URL
         */
        private String url;
        /**
         *
         */
        private String username;
        /**
         *
         */
        private String password;
    }
}

MultipleDataSource

package center.leon.oak.druid.abstract_routing_data_source.config;

import center.leon.oak.druid.abstract_routing_data_source.properties.DataSourceLeonProperties;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 11:31
 **/
@Component
public class MultipleDataSource extends AbstractRoutingDataSource implements InitializingBean {

    ThreadLocal<String> data_source_name = new ThreadLocal<>();

    @Autowired
    private DataSourceLeonProperties datasourceLeonProperties;

    @Override
    public void afterPropertiesSet() {
        init();
    }

    private void init() {
        // 设置默认数据源
        if (null != datasourceLeonProperties.getDefaultDataSourceLeon()) {
            DataSourceLeonProperties.DataSourceLeon dataSourceLeon = datasourceLeonProperties.getDefaultDataSourceLeon();
            DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
            druidDataSource.setDriverClassName(dataSourceLeon.getDriverClassName());
            druidDataSource.setUrl(dataSourceLeon.getUrl());
            druidDataSource.setUsername(dataSourceLeon.getUsername());
            druidDataSource.setPassword(dataSourceLeon.getPassword());
            super.setDefaultTargetDataSource(druidDataSource);
        }

        // 设置多数据源
        Map<Object, Object> targetDataSources = new HashMap<>();
        for (DataSourceLeonProperties.DataSourceLeon dataSourceLeon : datasourceLeonProperties.getDataSourceLeonList()) {
            DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
            druidDataSource.setDriverClassName(dataSourceLeon.getDriverClassName());
            druidDataSource.setUrl(dataSourceLeon.getUrl());
            druidDataSource.setUsername(dataSourceLeon.getUsername());
            druidDataSource.setPassword(dataSourceLeon.getPassword());

            targetDataSources.put(dataSourceLeon.getDataSourceName(), druidDataSource);
        }
        super.setTargetDataSources(targetDataSources);

        // 调用父类 afterPropertiesSet 方法
        // 将 targetDataSources 数据 填充到 resolvedDataSources 中
        // determineCurrentLookupKey 返回的 lookupKey 本质上是在 resolvedDataSources 中查找 dataSource 返回
        // 将 defaultTargetDataSource 数据 填充到 resolvedDefaultDataSource 中
        // resolvedDataSources 中 查找不到合适的 dataSource 时返回。
        super.afterPropertiesSet();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return data_source_name.get();
    }

    public void setDb_tb_name(String dataSourceName) {
        data_source_name.set(dataSourceName);
    }

    public void clearDb_tb_name() {
        data_source_name.remove();
    }
}

MonkeyDO

package center.leon.oak.druid.abstract_routing_data_source.dto;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 12:05
 **/
@Data
@TableName(value = "monkey")
@Accessors(chain = true)
public class MonkeyDO {
    private Long id;
    private String name;
    private Long version;
}

MonkeyMapper

package center.leon.oak.druid.abstract_routing_data_source.mapper;

import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 12:04
 **/
@Mapper
public interface MonkeyMapper extends BaseMapper<MonkeyDO> {
}

MonkeyService

package center.leon.oak.druid.abstract_routing_data_source.service;

import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 12:00
 **/
public interface MonkeyService {

    MonkeyDO get(Long id);

    MonkeyDO getInDataSource(Long id, String dataSourceName);
}

MonkeyServiceImpl

package center.leon.oak.druid.abstract_routing_data_source.service.impl;

import center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource;
import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
import center.leon.oak.druid.abstract_routing_data_source.mapper.MonkeyMapper;
import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 12:03
 **/
@Service
public class MonkeyServiceImpl implements MonkeyService {

    @Autowired
    private MonkeyMapper monkeyMapper;
    @Autowired
    private MultipleDataSource multipleDataSource;

    @Override
    public MonkeyDO get(Long id) {
        return monkeyMapper.selectById(id);
    }

    @Override
    public MonkeyDO getInDataSource(Long id, String dataSourceName) {
        try {
            multipleDataSource.setDb_tb_name(dataSourceName);
            return monkeyMapper.selectById(id);
        } finally {
            multipleDataSource.clearDb_tb_name();
        }
    }
}

PrintMonkey

package center.leon.oak.druid.abstract_routing_data_source.task;

import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 21:28
 **/
@Slf4j
@Component
public class PrintMonkey {

    @Autowired
    private MonkeyService monkeyService;

    @Scheduled(fixedRate = 6 * 1000)
    public void printMonkey_localhost() {
        MonkeyDO monkeyDO = monkeyService.getInDataSource(1L, "localhost");
        log.info("threadName : {}, monkey : {}", Thread.currentThread().getName(), monkeyDO);
    }

    @Scheduled(fixedRate = 6 * 1000)
    public void printMonkey_www_leon_center() {
        MonkeyDO monkeyDO = monkeyService.getInDataSource(1L, "www_leon_center");
        log.info("threadName : {}, monkey : {}", Thread.currentThread().getName(), monkeyDO);
    }
}

application-druid.properties

spring.datasource.type=center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource

spring.datasource.leon.data-source-leon-list[0].data-source-name=localhost
spring.datasource.leon.data-source-leon-list[0].driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.leon.data-source-leon-list[0].url=jdbc:mysql://localhost:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
spring.datasource.leon.data-source-leon-list[0].username=root
spring.datasource.leon.data-source-leon-list[0].password=Liang123,

spring.datasource.leon.data-source-leon-list[1].data-source-name=www_leon_center
spring.datasource.leon.data-source-leon-list[1].driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.leon.data-source-leon-list[1].url=jdbc:mysql://www.leon.center:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
spring.datasource.leon.data-source-leon-list[1].username=lmy
spring.datasource.leon.data-source-leon-list[1].password=Lmy123456,


spring.task.scheduling.pool.size=2

AbstractRoutingDataSourceApplication

package center.leon.oak.druid.abstract_routing_data_source;

import center.leon.oak.druid.abstract_routing_data_source.config.MultipleDataSource;
import center.leon.oak.druid.abstract_routing_data_source.dto.MonkeyDO;
import center.leon.oak.druid.abstract_routing_data_source.properties.DataSourceLeonProperties;
import center.leon.oak.druid.abstract_routing_data_source.service.MonkeyService;
import center.leon.oak.druid.abstract_routing_data_source.service.impl.MonkeyServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * @program: leon
 * @description:
 * @author: Leon
 * @create: 2021-07-22 11:28
 **/
@Slf4j
@EnableScheduling
@EnableConfigurationProperties
@SpringBootApplication
public class AbstractRoutingDataSourceApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(AbstractRoutingDataSourceApplication.class, args);
        DataSourceLeonProperties dataSourceLeonProperties = run.getBean(DataSourceLeonProperties.class);
        log.info("dataSourceLeonProperties : {}", dataSourceLeonProperties);
        MonkeyService monkeyService = run.getBean(MonkeyServiceImpl.class);

        final MultipleDataSource multipleDataSource = run.getBean(MultipleDataSource.class);

        multipleDataSource.setDb_tb_name("localhost");
        MonkeyDO monkey_1 = monkeyService.get(1L);
        log.info("monkey_1 : {}", monkey_1);
        multipleDataSource.clearDb_tb_name();

        multipleDataSource.setDb_tb_name("www_leon_center");
        MonkeyDO monkey_2 = monkeyService.get(1L);
        log.info("monkey_2 : {}", monkey_2);
        multipleDataSource.clearDb_tb_name();
    }
}

Console

2021-07-22 22:11:39.813  INFO 69282 --- [           main] d.a.AbstractRoutingDataSourceApplication : show Time ...
2021-07-22 22:11:39.813  INFO 69282 --- [           main] d.a.AbstractRoutingDataSourceApplication : dataSourceLeonProperties : DataSourceLeonProperties(defaultDataSourceLeon=null, dataSourceLeonList=[DataSourceLeonProperties.DataSourceLeon(dataSourceName=localhost, driverClassName=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://localhost:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false, username=root, password=Liang123,), DataSourceLeonProperties.DataSourceLeon(dataSourceName=www_leon_center, driverClassName=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://www.leon.center:3306/zoo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false, username=lmy, password=Lmy123456,)])
2021-07-22 22:11:39.864  INFO 69282 --- [   scheduling-2] com.alibaba.druid.pool.DruidDataSource   : {dataSource-2} inited
2021-07-22 22:11:39.864  INFO 69282 --- [           main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2021-07-22 22:11:40.026  INFO 69282 --- [           main] d.a.AbstractRoutingDataSourceApplication : monkey_1 : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:11:40.026  INFO 69282 --- [   scheduling-1] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:11:40.067  INFO 69282 --- [   scheduling-2] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
2021-07-22 22:11:40.075  INFO 69282 --- [           main] d.a.AbstractRoutingDataSourceApplication : monkey_2 : MonkeyDO(id=1, name=monkey sun, version=500)
2021-07-22 22:11:40.367  INFO 69282 --- [on(3)-127.0.0.1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-07-22 22:11:40.367  INFO 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-07-22 22:11:40.367 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Detected org.springframework.web.multipart.support.StandardServletMultipartResolver@42d0e41
2021-07-22 22:11:40.367 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Detected org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@48f2054d
2021-07-22 22:11:40.367 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Detected org.springframework.web.servlet.theme.FixedThemeResolver@6d6cd1e0
2021-07-22 22:11:40.368 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Detected DefaultRequestToViewNameTranslator
2021-07-22 22:11:40.369 TRACE 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Detected SessionFlashMapManager
2021-07-22 22:11:40.369 DEBUG 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2021-07-22 22:11:40.369  INFO 69282 --- [on(3)-127.0.0.1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
2021-07-22 22:11:45.812  INFO 69282 --- [   scheduling-1] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:11:45.824  INFO 69282 --- [   scheduling-2] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
2021-07-22 22:11:51.808  INFO 69282 --- [   scheduling-1] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:11:51.822  INFO 69282 --- [   scheduling-2] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
2021-07-22 22:11:57.807  INFO 69282 --- [   scheduling-1] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:11:57.818  INFO 69282 --- [   scheduling-2] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
2021-07-22 22:12:03.809  INFO 69282 --- [   scheduling-1] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:12:04.051  INFO 69282 --- [   scheduling-2] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
2021-07-22 22:12:09.811  INFO 69282 --- [   scheduling-1] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:12:09.824  INFO 69282 --- [   scheduling-2] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)
2021-07-22 22:12:15.810  INFO 69282 --- [   scheduling-1] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-1, monkey : MonkeyDO(id=1, name=write, version=2)
2021-07-22 22:12:15.821  INFO 69282 --- [   scheduling-2] c.l.o.d.a.task.PrintMonkey               : threadName : scheduling-2, monkey : MonkeyDO(id=1, name=monkey sun, version=500)

springboot在项目中集成 mysql,sqlserver多数据源项目源代码.zip springboot在项目中集成 mysql,sqlserver多数据源,,多数据源配置因为网上的很多都不能用,所以做完之后,就把自己的代码上来 立即下载

相关推荐

Bentley二次开发教程28-交互窗口-案例实战2-EC属性赋值工具

该工具会根据用户输入的路径获取Schema文件的路径,然后通过路径读取对应的Schema文件并在树状图中显示EC类,当用户选择树状图上的节点时,此时会触发事件,根据EC属性添加用户自定义控件用于显示EC属性并可对其进行赋值操作。完成后选取元素,点击界面上的应用,此时元素会被赋予指定EC类,同时修改的EC属性值也会被同步赋予。该工具涉及到的WinForm控件有:TextBox,Button,TreeView,Panel,UserControl(用户自定义控件)。

不见不散的博客 1473

springboot动态数据源用shardingjdbc按时间分表

1、背景: 原有项目架构 springboot mybatis-plus dynamic-datasource(动态数据源、mybatis-plus拓展) druid 连接池 根据业务数据不断增加,需要进行对业务量大的数据表行分表,因为以前的业务都是动态数据源管理datasource,改造可以顺势而为,把shardingjdbc的数据源也交给 dynamic-datasource 来管理,默认走以前不分表的逻辑,并且不由sharding管理,兼...

lixiaoyi01的博客 2460

三维重建之条纹投影结构光(三)——相位展开优化与多频外差实践

本文深入探讨了三维重建中条纹投影结构光技术的核心环节——相位展开优化。针对传统路径跟踪法存在的误差传播与路径依赖问题,重点解析了多频外差法的原理与优势,并通过详细的C++代码实践,展示了如何利用三频外差法实现鲁棒、高精度的相位展开,从而获得连续的绝对相位图,为后续三维点云生成奠定坚实基础。

weixin_29074295的博客 529

3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34344677的博客 925

ADS入门学习笔记——低噪声放大器(2)

1、输入匹配网络; 2、输出匹配网络;

weixin_42126696的博客 4988

2025-08-19利用opencv检测图片中文字及图片的坐标

该代码实现了图片中中文文本的检测与位置计算功能。主要使用CnOcr库进行OCR识别,结合OpenCV和PIL库处理图像。功能包括:1)检测图片中的中文文本及位置坐标;2)计算每个文本的像素宽度和高度;3)在原图上绘制文本边界框并标注识别结果。代码通过put_chinese_text函数解决中文显示问题,最终输出各文本内容、坐标位置及尺寸信息。适用于需要获取图片中文字精确位置的应用场景。

m0_58149406的博客 393

org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

qq 117791303 942

Global Mapper与ArcGIS双剑合璧:自动化与半自动矢量化提取地物轮廓实战

本文详细介绍了如何结合Global Mapper的自动化批量提取与ArcGIS的半自动精细修整功能,高效完成地物轮廓矢量化工作。通过实战案例,阐述了利用Global Mapper快速抓取初步轮廓,再借助ArcGIS的ArcScan等工具进行精细化编辑和优化的完整工作流,有效提升地理信息数据处理效率。

weixin_29284657的博客 118

AbstractRoutingDataSource,spring配置多数据源问题

在application.yml中添加配置 其中加了两个数据库配置 配置这两个数据源的主从关系, 及切换标识 使用aop方式自动切换数据源 参考: 配置参考: 【spring配置多数据源】spring连接多个数据库,同一套项目配置多个数据库 声明事务参考: mybatis(plus)多数据源

qq_27577113的博客 378

【Claude Code】Not logged in 未登录错误解决方案 + /login 认证路径

Claude Code 启动时提示 Not logged in 表示当前会话缺少有效凭证。本文从环境变量、API Key 配置、CI 自动化凭证脚本和系统时钟四个维度,提供完整的认证排查流程与修复方案。

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 891

STM32实战开发(65):STM32摄像头图像采集开发教程

我们将会详细介绍如何使用STM32进行摄像头控制、图像数据采集以及如何将采集到的图像数据传输到其他设备进行处理。通过这篇博客,您将能够掌握STM32与摄像头模块的图像采集技术,应用于各种图像处理场景。为了确保STM32能够正确接收图像数据,我们需要配置STM32的GPIO引脚,并通过外部中断捕获这些信号。为了实现更高效的图像采集,可以通过DMA进行数据传输,将图像数据直接从GPIO引脚存储到内存中。通过DMA传输,我们可以将采集到的图像数据直接存储在内存中的一个缓冲区,然后进行后续的图像处理。

2201_76125393的博客 2537

【原创】SSM框架(2):多数据源支持,动态配置依赖的数据源

一、SSM框架配置多数据源的原理   原理:MyBatis在创建SqlSession时,动态的使用不同的dataSource,就可以动态的使用不同的数据源。   那么,怎样才能动态的使用不同的dataSource呢? 在Spring框架中,提供了一个类AbstractRoutingDataSource,顾名思义叫做路由选择。该类AbstractRoutingDataSource继承Abstra...

weixin_33875564的博客 209

多源异构数据在线可视化ETL编排平台深度实践:基于Python与Apache Calcite的现代数据管道构建

在当今企业数据环境中,数据源呈现爆发式增长与高度异构性。传统ETL工具面对多源(MySQL、PostgreSQL、MongoDB、Hive、文件系统等)与异构(结构化、半结构化、非结构化)数据时,往往面临扩展性差、学习曲线陡峭、难以融入现代DevOps体系等问题。本文深入探讨了如何构建一个基于Python/Pandas、Apache Calcite(通过JPype桥接)以及Vue.js前端的轻量级、在线可视化ETL编排平台。

2201_76125261的博客 74

spring+druid多数据源配置

博客引用处(以下内容在原有博客基础上进行补充或更改,谢谢这些大牛的博客指导): spring+druid多数据源配置 druid多数据源配置 一、druid简介 Druid首先是一个数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。 Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接...

Willian的博客屋 6816

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Spring AbstractRoutingDataSource 多数据源切换原理

1.在spring中有一个抽象类AbstractRoutingDataSource类,通过这个类可以实现动态数据源切换。如下是这个类的成员变量 private Map<Object, Object> targetDataSources; private Object defaultTargetDataSource; private Map<Object, DataSource> resolvedDataSources; targetDataSources保存了key和数据库连接

weixin_38987366的博客 397

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

使用Spring的AbstractRoutingDataSource类实现多数据源切换

最近因为项目需要在做两个项目间数据同步的需求,具体是项目1的数据通过消息队列同步到项目2中,因为这个更新操作还涉及到更新多个库的数据,所以就需要多数据源切换的操作。下面就讲讲在Spring中如何进行数据源切换。这里是使用AbstractRoutingDataSource类来完成具体的操作,AbstractRoutingDataSource是Spring2.0后增加的。 QQ截图20170211220044.jpg 实现数据源切换的功能就是自定义一个类扩展AbstractRoutingDa..

疯一样的女子 585

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

利用Spring的AbstractRoutingDataSource解决多数据源的问题【代码手动切换,非AOP】

转: 利用Spring的AbstractRoutingDataSource解决多数据源的问题 多数据源问题很常见,例如读写分离数据库配置。 原来的项目出现了新需求,局方要求新增某服务器用以提供某代码,涉及到多数据源的问题。 解决方法如下: 1、首先配置多个datasource 1 <bean id="dataSource" class="org.apache...

weixin_30518397的博客 184

Spring, MyBatis 多数据源的配置和管理

同一个项目有时会涉及到多个数据库,也就是多数据源。多数据源又可以分为两种情况: 1)两个或多个数据库没有相关性,各自独立,其实这种可以作为两个项目来开发。比如在游戏开发中一个数据库是平台数据库,其它还有平台下的游戏对应的数据库; 2)两个或多个数据库是master-slave的关系,比如有mysql搭建一个 master-master,其后又带有多个slave;或者采用MHA搭建的master...

u013645129的博客 239

Mybatis多数据源的切换——AbstractRoutingDataSource

Spring数据源路由核心类AbstractRoutingDataSource,API文档解释如下: Abstract javax.sql.DataSource implementation that routes getConnection() calls to one of various target DataSources based on a lookup key. The latt...

天天向上 1356

Spring多数据源配置

在大型的应用中,为了提高数据库的水平伸缩性,对多个数据库实例进行管理,需要配置多数据源。在Spring框架被广泛运用的今天,可以很简单的运用Spring中的特性配置动态多数据。  1. 首先配置一个基于c3p0.ComboPooledDataSource的数据源A,数据源B. daoContext.xml

KindAzrael的专栏 1万+

基于Spring框架的简单多数据源切换解决办法

基于Spring框架的简单多数据源切换解决办法 Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法。我们仅仅需要实现一个简单的数据源选择算法就可以轻松的利用Spring框架实现数据源切换了。 Spring支持每次被操作的单数据源的事务。 1.继承AbstractRoutingDataSource并实...

177

【SpringBoot】多数据源切换

市面上常见的多数据源实现方案如下:方案1:基于Spring框架提供的AbstractRoutingDataSource。优点: 简单易用,支持动态切换数据源;适用于少量数据源情况。场景:适用于需要动态切换数据源,且数据库较少的情况。文档地址:方案2:使用MP提供的Dynamic-datasource多数据源框架。

精益求精 3661

AbstractRoutingDataSource动态数据源切换,AOP实现动态数据源切换

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.youkuaiyun.com/u012881904/article/details/77449710AbstractRoutingDataSource动态数据源切换上周末,室友通宵达旦的敲代码处理他的多数据源的问题,搞的非常的紧张,也和我聊了聊天,大概的了解了他...

weixin_30697239的博客 706

Spring集成多数据源及事务中切换数据源问题解析

多数据源应用场景 多数据源的应用很大程度上是为了满足多租户业务场景,多租户是一种软件架构技术,是实现如何在多用户环境下共用相同的系统或程序组件,并且可确保各用户间数据的隔离性,多租户的重点就是同一套程序下实现多用户数据的隔离。因此,多数据源就在这种场景下应运而生。 目前是实现多数据源的技术方案大致可以分为三类 1)每个用户都对应一个独立的数据库 2)每个用户共享数据库,同时每个用户对应一个独立的schema 3)通过在表中增加一个字段标识来区别数据所属的用户 上面三种数据隔离的实现方式都会有自己

demohui的博客 4369

Spring多数据源管理方案

数据库连接配置数据源配置继承AbstractRoutingDataSource,实现数据源切换逻辑在进行数据库操作时,切换到指定的数据源。

wsb_2526的博客 411
上一篇: SpringBoot 整合 Redis
下一篇: 日志打印 - 命令模式、模版方法模式
limeOracle
博客等级 码龄10年 11粉丝 566原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值