ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

若依框架多数据源实战:MySQL主库与SQLServer从库的配置与验证

若依框架多数据源实战:MySQL主库与SQLServer从库的配置与验证 1. 若依框架多数据源接入MySQL 主库与 SQLServer 从库的读写分离落地若依RuoYi是一套基于 Spring Boot 的快速开发脚手架很多团队拿它做后台管理系统。默认情况下它只配了一个 MySQL 数据源所有读写都走同一个库。当业务量上来之后报表查询、历史数据检索这类慢 SQL 会拖累主库写入性能这时候把查询分流到 SQLServer 从库就是一个很实际的选择。这篇内容聚焦的就是在若依框架里怎么把 MySQL 当主库负责写入、SQLServer 当从库负责查询通过DataSource注解做动态切换并且把连接验证的完整步骤走一遍。适合谁看如果你手上正好有一套若依项目数据库是 MySQL同时公司内部还有一套 SQLServer 的历史库或者报表库需要对接那这篇基本可以照着做。核心检索词就是若依框架多数据源配置涉及 MySQL 主库、SQLServer 从库、Druid 连接池、动态数据源注解这几个关键点。需要提前说清楚的是若依的多数据源机制本质上是 Spring 的AbstractRoutingDataSource做了一层封装通过 AOP 在方法执行前把数据源标识塞进 ThreadLocal然后路由到对应的连接池。理解这一点后面配置出问题的时候排查方向就清晰了。整个落地过程分几块先在application-druid.yml里把从库连接配上再补 SQLServer 的 JDBC 驱动依赖然后处理若依自带的SELECT 1 FROM DUAL健康检查语句SQLServer 没有 DUAL 虚拟表接着在需要走从库的 Service 方法上加注解最后用 telnet 和实际请求验证连通性。每一步我都会给出可直接复制的片段。另外提一句如果你在接入过程中需要临时验证某个模型或者接口的返回可以用 TaoToken 的模型对话功能快速试一下地址是 https://taotoken.net/api 不过这是辅助手段主线还是把数据源配通。2. 前置准备SQLServer 驱动依赖与 TaoToken 接入配置在动配置文件之前先把依赖和基础环境理清楚。若依默认的pom.xml里只有 MySQL 驱动SQLServer 的驱动需要手动加。这里有个坑SQLServer 的 JDBC 驱动有好几个版本sqljdbc4和mssql-jdbc是两个不同的 artifact选一个就行不要同时引入否则可能出现驱动类冲突。我实测下来JDK8 环境下用mssql-jdbc的7.4.1.jre8版本兼容性更好sqljdbc4的4.0版本在一些新一点的 SQLServer 实例上会报 TLS 相关的握手错误。所以推荐优先用下面这个!-- SQLServer 驱动包二选一推荐这个 -- dependency groupIdcom.microsoft.sqlserver/groupId artifactIdmssql-jdbc/artifactId version7.4.1.jre8/version /dependency如果你用的是老项目JDK 版本比较低那可以退回用sqljdbc4dependency groupIdcom.microsoft.sqlserver/groupId artifactIdsqljdbc4/artifactId version4.0/version /dependency加完依赖记得刷新 Maven确认com.microsoft.sqlserver.jdbc.SQLServerDriver这个类能被加载到。可以在 IDE 里用CtrlShiftT搜一下这个类名能搜到就说明依赖进来了。接下来是 TaoToken 的前置配置。为什么这里要提 TaoToken因为在多数据源调试阶段你可能会遇到需要快速验证某个 SQL 返回结构、或者让模型帮你分析报错日志的场景。TaoToken 提供了兼容 OpenAI 风格的 API 接入Base URL 是https://taotoken.net/api你需要在控制台生成一个 API Key然后在请求头里带上Authorization: Bearer 你的Key。具体操作路径先访问 https://taotoken.net/api-keys 生成 Key然后参考 https://taotoken.net/doc 里的接入文档配置。如果你用的是 Claude Code 这类编码工具可以走 https://taotoken.net/claude-code 的接入方式如果是长期做 Agent 开发Coding Plan 会更划算地址是 https://taotoken.net/coding-plan 。这里要强调一点TaoToken 是作为模型调用入口使用的不是数据库中间件也不涉及任何网络代理层面的操作。它的作用是在你调试数据源、分析异常堆栈的时候提供一个能快速对话的模型接口。配置的时候三件套要写全Base URL 填https://taotoken.net/apiKey 填你生成的令牌Model ID 按文档里支持的模型名填。环境层面还需要确认几件事SQLServer 服务是否允许远程连接、1433 端口是否开放、账号是否有对应库的读权限。这些在后面的验证章节会具体展开。3. 可复制配置application-druid.yml 从库数据源片段若依的数据源配置集中在ruoyi-admin/src/main/resources/application-druid.yml这个文件里。默认结构是spring.datasource.druid.master配主库slave配从库但默认enabled: false。我们要做的就是打开从库开关把连接信息换成 SQLServer 的。先看主库部分保持 MySQL 不变spring: datasource: druid: master: url: jdbc:mysql://127.0.0.1:3306/ry?useUnicodetruecharacterEncodingutf8zeroDateTimeBehaviorconvertToNulluseSSLtrueserverTimezoneGMT%2B8 username: root password: your_mysql_password driverClassName: com.mysql.cj.jdbc.Driver然后是关键的从库配置这里要改成 SQLServer 的连接串slave: # 从数据源开关/默认关闭 enabled: true url: jdbc:sqlserver://192.168.1.100:1433;SelectMethodCursor;DatabaseNameyour_db username: sa password: your_sqlserver_password driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver几个细节必须注意。第一enabled一定要改成true否则从库数据源根本不会初始化注解加了也没用。第二URL 里的SelectMethodCursor建议保留SQLServer 在返回大结果集时用游标模式能避免内存暴涨。第三DatabaseName后面跟的是具体库名不要带多余空格。第四driverClassName的包路径是com.microsoft.sqlserver.jdbc.SQLServerDriver大小写和拼写都不能错写错了启动时会报Cannot load driver class。配完从库之后还有一个若依特有的坑要处理。若依的 Druid 配置里默认带了健康检查的 validationQuery值是SELECT 1 FROM DUAL。这个语句在 MySQL 里没问题但 SQLServer 没有 DUAL 这个虚拟表执行会直接报错。所以要把从库的 validationQuery 改掉或者干脆去掉。在application-druid.yml的 druid 公共配置部分找到类似这样的段落# 配置检测连接是否有效 validationQuery: SELECT 1 FROM DUAL如果你希望主从都用一个配置可以改成SELECT 1这个语句在 MySQL 和 SQLServer 里都能跑。但更稳妥的做法是给从库单独指定不过若依默认结构里 validationQuery 是公共的所以直接改成SELECT 1最省事validationQuery: SELECT 1改完之后整个数据源配置就齐了。启动项目之前再检查一遍 YAML 缩进slave要和master同级都在druid下面。缩进错了会导致配置读不到从库静默不生效这种问题最难查。另外如果你在项目里用了多环境配置比如application-druid-dev.yml要确认改的是当前激活的那个文件。若依默认在application.yml里通过spring.profiles.active指定别改错了文件。4. 动态切换与验证DataSource 注解用法与连接测试配置写完之后怎么让查询走从库若依提供了DataSource注解加在 Service 类或者方法上就行。注解的值用DataSourceType.SLAVE表示从库DataSourceType.MASTER表示主库。先看一个典型的用法。假设你有一个报表查询的 ServiceService public class ReportServiceImpl implements IReportService { Autowired private ReportMapper reportMapper; Override DataSource(value DataSourceType.SLAVE) public ListReportVO selectHistoryReport(ReportQuery query) { return reportMapper.selectHistoryReport(query); } }这里DataSource(value DataSourceType.SLAVE)加在方法上表示这个方法执行期间所有数据库操作都路由到从库。方法执行完AOP 会把数据源标识清理掉不影响后续操作。如果加在类上那这个类里所有方法默认都走从库个别方法想走主库再单独加DataSource(value DataSourceType.MASTER)覆盖。有个细节要注意注解的生效依赖 AOP 代理所以同类内部方法直接调用this 调用是不会触发切换的。比如你在同一个 Service 里方法 A 调方法 B方法 B 上加了注解这种调用走的是原始对象注解不生效。解决办法是把方法 B 抽到另一个 Service或者通过注入自身代理来调用。配置和注解都就位后启动项目。启动日志里如果看到 Druid 初始化了两个数据源并且没有报错说明配置加载成功。可以搜一下日志里的slave关键字确认从库连接池被创建了。接下来做连接验证。第一步用 telnet 测端口telnet 192.168.1.100 1433如果连不上先检查 SQLServer 服务是否启动、TCP/IP 协议是否启用、防火墙有没有放行 1433 端口。Windows 上可以在「SQL Server 配置管理器」里确认 TCP/IP 状态防火墙里新建入站规则放行 1433。端口通了之后写一个简单的测试接口或者单元测试调用上面那个selectHistoryReport方法看能不能返回数据。如果返回了说明从库路由成功。如果报错看异常信息里连的是哪个库如果是 MySQL 的错说明注解没生效如果是 SQLServer 的错说明连上了但从库本身有问题。还有一种验证方式是用 JDBC 直连绕过若依的封装确认 SQLServer 本身可访问public class SqlServerTest { public static void main(String[] args) { try { Class.forName(com.microsoft.sqlserver.jdbc.SQLServerDriver); Connection con DriverManager.getConnection( jdbc:sqlserver://192.168.1.100:1433;databaseNameyour_db, sa, your_password); Statement st con.createStatement(); ResultSet rs st.executeQuery(SELECT TOP 10 * FROM your_table); while (rs.next()) { System.out.println(rs.getString(1)); } con.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } }这段代码能跑通说明 SQLServer 侧没问题剩下的就是若依配置的事了。跑不通的话根据异常信息定位常见的是账号密码错、库名错、或者 SQLServer 只允许 Windows 身份验证没开 SQL 验证。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth 问题多数据源接入过程中报错五花八门这里挑几个高频的对照排查。报错一Cannot load driver class: com.microsoft.sqlserver.jdbc.SQLServerDriver这个最直接驱动没进来。检查pom.xml里依赖是否加了、Maven 是否刷新了、driverClassName拼写是否正确。如果用的是sqljdbc4类路径是com.microsoft.sqlserver.jdbc.SQLServerDriver如果用的是mssql-jdbc类路径一样。确认依赖 scope 不是provided或者test。报错二SELECT 1 FROM DUAL执行失败提示对象名 DUAL 无效这就是前面说的 validationQuery 问题。SQLServer 没有 DUAL把validationQuery改成SELECT 1即可。改完重启Druid 的健康检查就能通过。报错三401 Unauthorized这个通常出现在你调用 TaoToken 接口做辅助调试的时候。原因一般是 API Key 没带、带错了、或者 Key 过期了。检查请求头Authorization: Bearer Key格式是否正确Key 是否从 https://taotoken.net/api-keys 正常生成。如果用的是 Claude Code 接入确认配置文件里的 Key 和 Base URL 对应Base URL 应该是https://taotoken.net/api。报错四local proxy failed或连接超时这个报错一般和网络层有关。先确认 SQLServer 的 1433 端口是否可达用 telnet 测。如果 telnet 不通检查防火墙入站规则、SQLServer 的 TCP/IP 协议是否启用、是否只监听了 localhost。注意这里说的是数据库连接层面的网络配置不涉及任何代理工具的使用。报错五reading choices相关解析异常这个报错多见于调用模型接口返回结构不符合预期时。如果你在调试过程中用模型接口分析 SQL 日志返回的 JSON 结构里choices字段解析失败检查一下请求的 Model ID 是否正确、返回体是不是被截断了。TaoToken 的接入文档里有各模型的返回格式说明对照一下。报错六OAuth 相关报错如果你用的是 Claude Code 或者 Codex 这类工具接入可能会碰到 OAuth 认证流程的问题。这类工具通常需要配置auth.json或者类似的凭证文件。以 Codex 为例auth.json里要写清楚 Base URL、Key 和 Model ID 三件套。Base URL 填https://taotoken.net/apiKey 填生成的令牌Model ID 按文档支持的填。三件套缺一个都会认证失败。排查思路总结一下先看报错信息里连的是哪个库判断是主库问题还是从库问题再看是配置加载阶段报错还是运行阶段报错配置阶段多半是 YAML 缩进、驱动类名、依赖缺失运行阶段多半是网络、权限、SQL 语法差异。按这个顺序查基本能定位到。6. 长期编码与 Agent 场景下的接入建议数据源配通只是第一步后面在长期维护和 Agent 开发场景里还有几个实践建议。第一主从切换的注解尽量加在 Service 层不要加在 Controller 或者 Mapper 层。加在 Controller 层粒度太粗一个请求里可能既有写又有读加在 Mapper 层则太细每个查询方法都要加维护成本高。Service 层是业务逻辑的边界加在这里最合适。第二从库查询要注意数据一致性。MySQL 主库写入后如果 SQLServer 从库是通过某种同步机制拿数据的可能存在延迟。对一致性要求高的查询比如刚写入就要读出来的场景还是走主库。只有报表、历史数据这类对实时性要求不高的查询才分流到从库。第三如果你在用 Claude Code 或者类似的编码工具做日常开发可以把数据源配置、注解用法这些整理成项目内的规范文档让工具在生成代码时参考。TaoToken 的 Coding Plan 适合这种长期编码场景地址是 https://taotoken.net/coding-plan 接入后可以在编码过程中随时调用模型做代码审查或者报错分析。第四配置文件里的密码不要明文提交到 Git。若依支持用 Jasypt 加密或者用环境变量注入。生产环境的数据库密码尤其要注意别图省事直接写死在 YAML 里。第五多数据源场景下事务管理要特别小心。Spring 的Transactional默认只对主数据源生效如果在一个事务方法里同时操作主库和从库从库的操作不会回滚。所以跨库写操作要拆开或者用分布式事务方案但这个复杂度就上去了。大多数读写分离场景下从库只读不涉及写事务问题不大。最后如果你在接入过程中需要查文档或者验证接口TaoToken 的接入文档在 https://taotoken.net/doc API Key 在 https://taotoken.net/api-keys 模型对话功能在 https://taotoken.net/api 。这几个入口按需使用核心还是把若依的数据源配置和注解切换机制吃透。配置改完记得重启验证别改一半就提交了。
返回列表