第50篇-多数据源集成
【Kotlin Spring Boot 4 从零到架构师】第 50 篇多数据源集成本系列定位零基础入门从 Kotlin 语法一路到 Spring Boot 4 高级架构DDD Modulith适合 Java 开发者转型也适合纯新手系统学习。本篇你将学到多数据源的应用场景多数据源配置策略Primary/Qualifier的使用主库PostgreSQL 分析库ClickHouse的双数据源实战学完本篇你将能让 mini-shop 同时连接多个数据库各司其职。一、为什么需要多数据源1.1 典型场景场景数据源 A数据源 B读写分离主库写从库读业务 分析PostgreSQL业务ClickHouse统计分析多租户主租户库独立租户库迁移过渡旧数据库新数据库1.2 mini-shop 场景PostgreSQL主库商品、订单、用户 —— 高频读写 ClickHouse分析库订单统计、销量报表 —— 低频大量查询下面是 mini-shop 多数据源架构总览ClickHouse 分析库PostgreSQL 主库mini-shop 应用JPA / PrimaryNamedParameterJdbcTemplate / Qualifier业务 Service分析 AnalyticsService订单表商品表用户表订单统计销量报表二、配置两个数据源2.1 添加依赖dependencies{implementation(org.springframework.boot:spring-boot-starter-data-jpa)runtimeOnly(org.postgresql:postgresql)runtimeOnly(com.clickhouse:clickhouse-jdbc:0.7.0)}2.2 application.ymlspring:datasource:# 主数据源PostgreSQL—— 业务数据url:jdbc:postgresql://localhost:5432/mini_shopusername:postgrespassword:postgres123driver-class-name:org.postgresql.Driverhikari:pool-name:PrimaryPool# 自定义分析数据源配置analytics:datasource:url:jdbc:clickhouse://localhost:8123/mini_shop_analyticsusername:defaultpassword:driver-class-name:com.clickhouse.jdbc.ClickHouseDriverhikari:pool-name:AnalyticsPoolmaximum-pool-size:52.3 主数据源配置packagecom.example.minishop.configimportorg.springframework.boot.autoconfigure.jdbc.DataSourcePropertiesimportorg.springframework.boot.context.properties.ConfigurationPropertiesimportorg.springframework.boot.jdbc.autoconfigure.DataSourcePropertiesasBootDataSourcePropertiesimportorg.springframework.context.annotation.Beanimportorg.springframework.context.annotation.Configurationimportorg.springframework.context.annotation.Primaryimportorg.springframework.data.jpa.repository.config.EnableJpaRepositoriesimportjavax.sql.DataSourceConfigurationEnableJpaRepositories(basePackages[com.example.minishop.product,com.example.minishop.order,com.example.minishop.user],entityManagerFactoryRefprimaryEntityManagerFactory,transactionManagerRefprimaryTransactionManager)classPrimaryDataSourceConfig{BeanPrimaryConfigurationProperties(spring.datasource)funprimaryDataSourceProperties():DataSourceProperties{returnDataSourceProperties()}BeanPrimaryfunprimaryDataSource():DataSource{returnprimaryDataSourceProperties().initializeDataSourceBuilder().build()}}2.4 分析数据源配置packagecom.example.minishop.configimportorg.springframework.boot.context.properties.ConfigurationPropertiesimportorg.springframework.context.annotation.Beanimportorg.springframework.context.annotation.Configurationimportorg.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplateimportjavax.sql.DataSourceConfigurationclassAnalyticsDataSourceConfig{BeanConfigurationProperties(spring.analytics.datasource)funanalyticsDataSourceProperties():DataSourceProperties{returnDataSourceProperties()}Bean(analyticsDataSource)funanalyticsDataSource():DataSource{returnanalyticsDataSourceProperties().initializeDataSourceBuilder().build()}Bean(analyticsJdbcTemplate)funanalyticsJdbcTemplate(Qualifier(analyticsDataSource)dataSource:DataSource):NamedParameterJdbcTemplate{returnNamedParameterJdbcTemplate(dataSource)}}2.5 使用分析数据源ServiceclassAnalyticsService(Qualifier(analyticsJdbcTemplate)privatevalanalyticsJdbc:NamedParameterJdbcTemplate){/** * 查询每日销售统计 */fungetDailySalesStats(startDate:String,endDate:String):ListDailySalesStat{valsql SELECT toDate(created_at) AS date, count() AS order_count, sum(total_amount) AS total_revenue, avg(total_amount) AS avg_order_value FROM orders WHERE created_at BETWEEN :start AND :end AND status PAID GROUP BY date ORDER BY date .trimIndent()valparamsmapOf(starttostartDate,endtoendDate)returnanalyticsJdbc.query(sql,params){rs,_-DailySalesStat(daters.getString(date),orderCountrs.getLong(order_count),totalRevenuers.getBigDecimal(total_revenue),avgOrderValuers.getBigDecimal(avg_order_value))}}}dataclassDailySalesStat(valdate:String,valorderCount:Long,valtotalRevenue:BigDecimal,valavgOrderValue:BigDecimal)下面是双数据源配置与注入的完整流程Service 层Repository 层Bean 定义配置层application.ymlspring.datasource (PG)spring.analytics.datasource (CH)PrimaryDataSourceConfigConfigurationPropertiesPrimaryAnalyticsDataSourceConfigConfigurationPropertiesprimaryDataSource (PG)PrimaryanalyticsDataSource (CH)analyticsJdbcTemplateNamedParameterJdbcTemplateEnableJpaRepositoriesproduct / order / userOrderService自动注入 PrimaryAnalyticsServiceQualifier 指定三、关键注意事项3.1 Primary 的作用当 Spring 容器中有多个DataSourceBean 时Primary标记的 Bean 是默认选择。Liquibase、Spring Data JPA 自动配置默认会用Primary的数据源。BeanPrimary// ← 主数据源Spring Boot 自动配置用这个funprimaryDataSource():DataSource{...}3.2 Qualifier 精确指定// 不用 Primary 时必须用 Qualifier 指定ServiceclassAnalyticsService(Qualifier(analyticsDataSource)// ← 精确指定分析数据源privatevalanalyticsDataSource:DataSource)3.3 ClickHouse autoCommit 陷阱ClickHouse 的 JDBC 驱动要求autoCommit true与 PostgreSQL 不同spring:analytics:datasource:hikari:auto-commit:true# ClickHouse 必须为 true3.4 Liquibase 只在主数据源spring:liquibase:change-log:classpath:db/changelog/db.changelog-master.yaml# Liquibase 默认用 Primary 数据源不需要额外配置四、Primary vs Qualifier 决策方式特点场景Primary全局默认选择主数据源90% 用这个Qualifier(name)精确指定分析数据源、特定场景原则主数据源用Primary其他数据源用Qualifier显式注入。下面是数据源选择决策流程图是否是否是否需要注入 DataSource只有一个 DataSource BeanSpring 自动注入无需额外注解该数据源是主业务数据源标记 Primary全局默认选择注入点明确知道要哪个数据源使用 Qualifier(beanName)精确指定编译报错NoUniqueBeanDefinitionExceptionLiquibase / JPA 自动配置默认使用 Primary手动指定注入如 analyticsDataSource本篇小结知识点核心内容多数据源业务库 分析库 / 读写分离Primary标记主数据源默认选择Qualifier精确指定注入哪个数据源ConfigurationProperties绑定各数据源配置EnableJpaRepositories指定 Repository 用哪个数据源NamedParameterJdbcTemplate非 JPA 的数据源操作ClickHouse autoCommit必须为trueLiquibase只在主数据源下篇预告第 51 篇Kotlin 协程在 Spring Boot 中的应用Spring Boot 4 支持协程 Controller下一篇学习suspend函数在 Web 层、数据访问层的实际应用以及虚拟线程的对比。如果本篇内容对你有帮助欢迎点赞收藏有任何疑问欢迎在评论区交流。

相关新闻

Vue3+Element Plus全局图标管理:从手动引入到自动化方案实战

Vue3+Element Plus全局图标管理:从手动引入到自动化方案实战

1. 项目概述:为什么我们需要全局管理图标? 在Vue3和Element Plus的项目里,图标的使用频率高得惊人。从导航菜单的箭头、按钮里的加号,到表格的操作栏、表单的状态提示,几乎无处不在。早期开发时,我们可能习…

2026/11/13 1:50:36 阅读更多 →
ANSYS APDL中ASEL命令详解:从基础语法到高级应用场景

ANSYS APDL中ASEL命令详解:从基础语法到高级应用场景

1. 项目概述:为什么ASEL命令是APDL建模的“手术刀”?在ANSYS APDL这个以命令流为核心驱动的经典仿真环境中,每一个建模、加载、求解和后处理动作,本质上都是对数据库中几何与有限元对象的精准“选取”与“操作”。而ASEL命令&…

2026/11/6 4:00:06 阅读更多 →
Android Studio打包APK全流程详解:从签名配置到优化发布

Android Studio打包APK全流程详解:从签名配置到优化发布

1. 项目概述:从代码到可安装应用的关键一跃对于每一位Android开发者来说,无论你是刚入门的新手,还是已经写过几万行代码的老手,最终都需要面对同一个问题:如何把自己的心血结晶——那一行行代码、一个个界面——变成一…

2026/11/14 1:49:39 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/14 5:13:29 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/14 5:13:29 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/14 5:13:29 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/14 2:41:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/14 5:13:29 阅读更多 →

日新闻

周新闻

月新闻