数据库读取数据源配置实现动态数据源

概述

项目中整合多数据源时,一般是通过读取配置文件中的数据源信息创建数据源 放到AbstractRoutingDataSource的targetDataSources的map中, 然后通过AbstractRoutingDataSource获取实际需要的数据源。

当项目中需要整合的数据源特别多的时候,比如:8个、16个、32个数据库等, 这个时候配置文件就会变得比较臃肿,而且现在主流的是微服务架构, 可能一套服务有多个模块,如果是通过配置文件进行配置,那么需要 修改的配置文件相对较多,这种情况可以通过数据库进行配置数据源 或者是通过配置中心进行配置。

下面将演示通过数据库配置所有的数据源,服务只需要配置默认的数据源, 通过默认的数据源读取配置的多数据源,然后创建数据源实例,最后将 创建的数据源实例放在AbstractRoutingDataSource中。

环境说明

  • spring boot
  • mysql
  • mybatis-plus
  • spring-aop
  • druid
  • redis

项目目录结构

  • controller: 存放接口类
  • service: 存放服务类
  • mapper: 存放操作数据库的mapper接口
  • model: 存放数据库表实体类
  • vo: 存放返回给前端的视图类

  • context: 线程公共上下文
  • config: 数据源配置信息
  • annotation: 实现动态数据源加载自定义注解
  • aop: 实现动态数据源设置切面类
  • util: 工具类
  • constants: 常量类

关键类说明

  • SpringContextUtils: 获取手动获取Spring容器中的bean, 包含ApplicationContext属性
  • DynamicContextHolder: 当前线程持有的数据源key, 包含ThreadLocal属性
  • DataSourceCachePool: 数据源缓存池
  • DynamicDataSource: 动态数据源配置类
  • DynamicDataSourceConfig: 数据源配置类
  • DynamicDataSourceFactory: 数据源工厂
  • DataSourceRoute: 动态设置数据源key注解
  • DbKey: 指定数据源key参数注解
  • DynamicDataSource: 指定动态数据源方法注解
  • DataSourceAspect: 动态数据源注解切面
  • DynamicDataSourceAspect: 指定动态数据源切面
  • DynamicDBUtil: 动态数据源工具

简要设计

1、设计数据源配置表,表结构就按实际配置数据源所需要的属性,可以参考DataSourceProperties进行字段设计

CREATE TABLE `t_dynamic_datasource` (
     `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
     `datasource_name` varchar(20) DEFAULT '' COMMENT '数据源名称',
     `datasource_url` varchar(200) DEFAULT '' COMMENT '数据源url',
     `db_driver` varchar(200) DEFAULT '' COMMENT '数据源url',
     `datasource_account` varchar(50) DEFAULT '' COMMENT '数据源帐号',
     `datasource_password` varchar(64) DEFAULT '' COMMENT '数据源密码',
     `remark` varchar(200) DEFAULT NULL COMMENT '备注',
     `is_show_type` tinyint(1) DEFAULT NULL COMMENT '数据源可见类型(1-全部人可见,2-部分人可见)',
     `datasource_type` tinyint(1) DEFAULT NULL COMMENT '默认mysql,暂时只支持mysql',
     `update_name` varchar(20) DEFAULT '' COMMENT '更新人',
     `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
     `create_code` int(11) unsigned DEFAULT '0' COMMENT '创建人工号',
     `create_name` varchar(20) DEFAULT '' COMMENT '创建人',
     `update_code` int(11) unsigned DEFAULT '0' COMMENT '更新人工号',
     `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
     `deleted_flag` tinyint(1) DEFAULT '0' COMMENT '是否删除',
     PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='数据源 ';

构建默认的数据源作为AbstractRoutingDataSource的defaultTargetDataSource属性的值,默认的数据源就是上一步创建配置表的数据库, 这个数据源的作用就是读取配置在其数据库表中其他数据源配置信息

3、标注有@DataSourceRoute注解的方法或者类被请求时,先通过AOP设置对应的数据源到AbstractRoutingDataSource中

4、动态数据源构建工具首先从本地数据源缓存池中查找,找到直接使用放入AbstractRoutingDataSource, 未找到再从缓存或者数据库中直接读取数据源配置信息,然后构建数据源

5、构建的动态数据源存放到本地缓存池中一份,以及Spring抽象出的AbstractRoutingDataSource数据源一份

6、数据源准备完成后,在将动态数据源的kye放入到本地线程的持有对象中。这个持有对象包含一个ThreadLocal变量,线程key就是存放其中

7、动态数据源的key除了可以通过自己的动态数据源注解进行设置外,也可以通过自定义注解表示请求参数进行动态的设置数据源key

总结

共有两种方式设置动态数据源key。第一种通过动态数据源注解的方式设置数据源key, 该方式是在项目加载时就已经固定了,不是特别灵活。第二种是通过方法参数传递数据源key, 通过自定义注解表示传入的参数是数据源key,这种方式同样地请求可以通过参数实现每次请求 都可以动态的改变数据源。

请求流程图:

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: RDD转换为DataFrame可以通过SparkSession的read方法实现文本文件数据源读取。具体步骤如下: 1. 创建SparkSession对象 ```python from pyspark.sql import SparkSession spark = SparkSession.builder.appName("text_file_reader").getOrCreate() ``` 2. 使用SparkSession的read方法读取文本文件 ```python text_file = spark.read.text("path/to/text/file") ``` 3. 将RDD转换为DataFrame ```python df = text_file.toDF() ``` 完整代码示例: ```python from pyspark.sql import SparkSession spark = SparkSession.builder.appName("text_file_reader").getOrCreate() text_file = spark.read.text("path/to/text/file") df = text_file.toDF() df.show() ``` 其中,"path/to/text/file"为文本文件的路径。 ### 回答2: 要将RDD转换为DataFrame以实现文本文件数据源读取,您可以遵循以下步骤: 1. 首先,导入必要的库。您需要导入SparkSession和pyspark.sql.functions。 2. 创建一个SparkSession对象,它将负责连接Spark集群。可以使用如下代码创建SparkSession: `spark = SparkSession.builder.appName("RDD to DataFrame").getOrCreate()` 3. 读取文本文件并创建一个RDD。您可以使用SparkContext的textFile()方法来读取文本文件,并将其存储在一个RDD中。示例如下: `text_rdd = spark.sparkContext.textFile("file_path")` 其中,"file_path"是文本文件的路径。 4. 使用map()函数将每一行的字符串分割为字段,并创建一个新的RDD。示例如下: `rdd = text_rdd.map(lambda line: line.split(","))` 这将创建一个包含列表的RDD,其中每个列表表示一行文本文件。 5. 定义一个模式以指定DataFrame的结构。使用pyspark.sql.types中的StructType和StructField来指定模式。例如,如果每行都有两个字段(name和age),则可以使用如下代码定义模式: ``` from pyspark.sql.types import StructType, StructField, StringType, IntegerType schema = StructType([StructField("name", StringType(), True), StructField("age", IntegerType(), True)]) ``` 在这个示例中,name字段的数据类型是StringType,age字段的数据类型是IntegerType。 6. 使用toDF()函数将RDD转换为DataFrame,并将模式作为参数传递。示例如下: `df = rdd.toDF(schema)` 这将创建一个DataFrame,其中每个字段的名称和类型与模式中定义的一致。 现在,您可以对DataFrame执行各种操作,比如过滤、聚合和显示数据。 ### 回答3: RDD转换为DataFrame可以实现文本文件数据源读取。DataFrame是一种更高级别的数据抽象,它提供了类似于关系型数据库表的结构,可以更方便地进行数据分析和处理。 要将RDD转换为DataFrame,首先需要创建一个RDD对象,然后使用其中的数据创建一个DataFrame对象。下面是一个示例代码: ```python # 导入必要的库 from pyspark.sql import SQLContext # 创建SparkSession对象 spark = SparkSession.builder.getOrCreate() # 创建SQLContext对象,用于操作数据 sqlContext = SQLContext(spark.sparkContext) # 读取文本文件数据,创建RDD对象 rdd = spark.sparkContext.textFile("文件路径") # 转换为DataFrame对象 df = sqlContext.createDataFrame(rdd.map(lambda x: x.split(" "))) # 打印DataFrame的内容 df.show() ``` 在上面的代码中,首先创建了一个SparkSession对象,然后创建了一个SQLContext对象。接下来,使用`textFile`方法读取文本文件数据,并创建了一个RDD对象。最后,使用`createDataFrame`方法将RDD转换为DataFrame对象。 在实际应用中,可以根据需要对DataFrame进行进一步的操作和处理,例如筛选数据、聚合数据等。通过DataFrame可以更方便地进行数据探索和分析,提高数据处理的效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值