当前位置: 首页 > article >正文

SQLx:一款优秀的异步 SQL 工具库

SQLx一款优秀的异步 SQL 工具库传统 ORM 工具会引入冗余抽象而原生 SQL 操作又容易出现运行时错误。SQLx 作为 Rust 生态中备受推崇的 SQL 工具库以编译时 SQL 验证为核心卖点兼顾异步支持、轻量等特性解决了上述痛点。本文将从 SQLx 将逐步讲解其特性、快速上手流程、实战案例及进阶用法带读者快速掌握这一强大工具。SQLx 介绍SQLx 是一个纯 Rust 编写的异步 SQL 工具库并非传统意义上的 ORM更偏向是类型安全的 SQL 执行器。它的核心设计理念是将 SQL 的验证从运行时提前到编译时通过宏在编译期与数据库建立临时连接校验SQL语法、字段名、数据类型的合法性从源头避免大量低级错误。与其他 Rust 数据库工具如 Diesel、SeaORM 等相比SQLx 具有以下鲜明特点无 DSL领域特定语言直接使用原生 SQL无需学习额外的查询语法降低学习成本同时保留 SQL 的灵活性。异步优先基于 tokio 等异步运行时设计适配 Rust 异步生态性能优于同步数据库工具。多数据库支持支持 PostgreSQL、MySQL、SQLite 等主流数据库切换数据库时无需大幅修改代码。轻量无依赖核心功能简洁不引入过多冗余依赖编译速度快适合各类 Rust 项目。简单来说SQLx 的目标是让开发者既能享受原生 SQL 的灵活又能获得 Rust 的类型安全和编译时检查同时兼顾异步场景的性能需求。特性讲解编译时SQL验证传统 SQL 操作中SQL 语法错误、字段名拼写错误、字段类型不匹配等问题只有在程序运行时执行 SQL 才能发现增加了调试成本和线上风险。而 SQLx 通过query!、query_as!等宏在编译期就会连接数据库对 SQL 语句进行全方位校验。实现原理编译时SQLx 的宏会读取环境变量中的数据库连接地址如 DATABASE_URL建立临时只读连接将 SQL 语句发送给数据库进行解析和校验校验通过后才会继续编译若 SQL 存在错误比如字段名错误、语法错误则直接编译失败给出明确的错误提示。示例编译时报错若数据库中users表不存在agee字段以下代码会在编译时直接报错无需运行程序// 编译时会报错column agee does not existletuser:Usersqlx::query_as!(User,SELECT id, name, agee FROM users WHERE id $1,1).fetch_one(pool).await?;异步支持与连接池SQLx 基于异步 I/O 设计完全兼容 tokio、async-std 等 Rust 主流异步运行时无需额外适配即可在异步项目中使用。同时SQLx 内置了高效的连接池实现自动管理数据库连接的创建、复用和释放避免频繁建立连接带来的性能开销。连接池带来的好处有限制最大连接数防止数据库因连接过多而崩溃。复用空闲连接减少 TCP 握手和认证的开销提升查询性能。自动处理连接超时和重连提升系统稳定性。SQLx 提供了PgPoolPostgreSQL、MySqlPoolMySQL等连接池类型配置简单可根据项目需求调整连接池大小、超时时间等参数。结构体自动映射SQLx 支持将查询结果自动映射到 Rust 结构体无需手动解析查询结果如逐字段读取、类型转换大幅简化代码。只需为结构体实现FromRow特征可通过派生宏自动实现即可通过query_as!宏直接将查询结果映射为结构体实例。usesqlx::FromRow;// 派生 FromRow 特征#[derive(Debug, FromRow)]structUser{id:i32,name:String,email:OptionString,// 可选字段对应数据库中的 NULLcreated_at:chrono::NaiveDateTime,// 支持时间类型自动转换}// 查询单条记录并映射为 User 结构体letuser:Usersqlx::query_as!(User,SELECT id, name, email, created_at FROM users WHERE id $1,1).fetch_one(pool).await?;println!({:?},user);事务支持SQLx 提供了完善的事务支持同时支持嵌套事务通过保存点机制实现确保数据一致性。此外SQLx 还提供了事务闭包模式自动处理事务的提交和回滚减少手动操作的冗余代码降低出错风险。迁移工具Migrations数据库迁移是项目迭代过程中不可或缺的环节SQLx 内置了迁移工具 sqlx-cli支持创建、应用、回滚迁移脚本统一管理数据库表结构的变更。迁移脚本采用 SQL 文件编写支持版本控制。快速上手下面以 PostgreSQL 为例讲解 SQLx 的环境搭建、连接数据库、以及基础 CRUD 操作。环境准备安装依赖在Cargo.toml中添加 SQLx 依赖并指定数据库类型和异步运行时 tokio安装 sqlx-cli 迁移工具通过 Cargo 安装 sqlx-cli用于管理数据库迁移cargoinstallsqlx-cli配置数据库连接创建.env文件配置数据库连接地址这里改为你实际的数据库连接配置DATABASE_URLpostgres://username:passwordlocalhost:5432/sqlx_demo基础 CRUD 操作创建迁移脚本创建 users 表使用 sqlx-cli 创建迁移脚本用于创建users表sqlx migrateadd-rcreate_users执行后会在项目根目录生成migrations文件夹并同步创建迁移与回滚这两个脚本文件XXXXXX_create_users.up.sqlXXXXXX_create_users.down.sql编辑迁移脚本文件CREATETABLEIFNOTEXISTSusers(idSERIALPRIMARYKEY,nameVARCHAR(50)NOTNULL,emailVARCHAR(100)UNIQUE,created_atTIMESTAMPNOTNULLDEFAULTNOW());编辑回滚脚本文件DROPTABLEIFEXISTSusers;执行迁移命令sqlx migrate run编写代码编辑src/main.rs实现用户的新增、查询、更新、删除usechrono::NaiveDateTime;usedotenvy::dotenv;usesqlx::{PgPool,prelude::FromRow};// 定义 User 结构体与 users 表对应#[derive(Debug, FromRow)]structUser{id:i32,name:String,email:OptionString,created_at:NaiveDateTime,}// 初始化数据库连接池asyncfninit_pool()-PgPool{dotenv().ok();letdatabase_urlstd::env::var(DATABASE_URL).expect(DATABASE_URL environment variable not set);PgPool::connect(database_url).await.expect(Failed to connect to database)}// 新增用户asyncfncreate_user(pool:PgPool,name:str,email:Optionstr)-ResultUser,sqlx::Error{letusersqlx::query_as!(User,INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *,name,email).fetch_one(pool).await?;Ok(user)}// 根据ID查询用户asyncfnget_user_by_id(pool:PgPool,id:i32)-ResultOptionUser,sqlx::Error{letusersqlx::query_as!(User,SELECT * FROM users WHERE id $1,id).fetch_optional(pool).await?;Ok(user)}// 更新用户名称asyncfnupdate_user_name(pool:PgPool,id:i32,new_name:str)-Resultu64,sqlx::Error{letresultsqlx::query!(UPDATE users SET name $1 WHERE id $2,new_name,id).execute(pool).await?;Ok(result.rows_affected())// 返回受影响的行数}// 删除用户asyncfndelete_user(pool:PgPool,id:i32)-Resultu64,sqlx::Error{letresultsqlx::query!(DELETE FROM users WHERE id $1,id).execute(pool).await?;Ok(result.rows_affected())}#[tokio::main]asyncfnmain()-Result(),sqlx::Error{// 初始化连接池letpoolinit_pool().await;println!(Connected to database successfully!);// 新增用户letnew_usercreate_user(pool,Alice,Some(aliceexample.com)).await?;println!(Created user: {:?},new_user);// 根据ID查询用户letuserget_user_by_id(pool,new_user.id).await?;println!(Found user: {:?},user);// 更新用户名称letaffected_rowsupdate_user_name(pool,new_user.id,Alice Smith).await?;println!(Updated {} rows,affected_rows);// 删除用户letaffected_rowsdelete_user(pool,new_user.id).await?;println!(Deleted {} rows,affected_rows);Ok(())}SQLx 进阶连接池优化配置默认的连接池配置可能无法满足高并发场景的需求可通过PgPoolOptionsPostgreSQL自定义连接池参数优化性能usedotenvy::dotenv;usesqlx::postgres::PgPoolOptions;asyncfninit_optimized_pool()-PgPool{letdatabase_urlstd::env::var(DATABASE_URL).expect(DATABASE_URL not set);PgPoolOptions::new().max_connections(20)// 最大连接数根据数据库性能调整.min_connections(5)// 最小空闲连接数减少连接建立开销.acquire_timeout(std::time::Duration::from_secs(3))// 连接获取超时时间.idle_timeout(std::time::Duration::from_secs(60))// 空闲连接超时时间.connect(database_url).await.expect(Failed to create optimized pool)}批量操作优化在需要批量插入、更新数据时应当避免循环调用单条操作这会导致频繁与数据库交互严重影响性能可以使用 SQLx 的批量操作功能减少数据库交互次数。// 新建用户专用结构体#[derive(Debug)]pubstructNewUser{pubname:String,pubemail:OptionString,}asyncfnbatch_insert_users(pool:PgPool,new_users:VecNewUser,)-ResultVecUser,sqlx::Error{ifnew_users.is_empty(){returnOk(Vec::new());}// 开启事务letmuttxpool.begin().await?;// 动态生成批量插入的占位符($1,$2), ($3,$4), ...letplaceholders:VecStringnew_users.iter().enumerate().map(|(i,_)|format!((${}, {}),i*21,i*22)).collect();// 构建完整 SQLletsqlformat!(INSERT INTO users (name, email) VALUES {} RETURNING id, name, email, created_at,placeholders.join(, ));// 绑定所有参数letmutquerysqlx::query_as::_,User(sql);foruserinnew_users{queryquery.bind(user.name).bind(user.email);}// 执行letusers:VecUserquery.fetch_all(mut*tx).await?;// 提交事务tx.commit().await?;Ok(users)}事务进阶嵌套事务与保存点SQLx 支持嵌套事务通过保存点Savepoint机制实现当嵌套事务失败时仅回滚当前嵌套层级的操作不影响外层事务。asyncfnnested_transaction_example(pool:PgPool)-Result(),sqlx::Error{letmuttxpool.begin().await?;// 外层事务操作插入用户letusersqlx::query_as!(User,INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *,Bob,Some(bobexample.com)).fetch_one(mut*tx).await?;// 创建保存点等价于嵌套事务sqlx::query(SAVEPOINT nested_tx).execute(mut*tx).await?;// 嵌套事务内操作更新用户名sqlx::query!(UPDATE users SET name $1 WHERE id $2,Bob Brown,user.id// 修复弃用 last_insert_id()直接用结构体id).execute(mut*tx).await?;// 回滚到保存点仅撤销嵌套内的操作不影响外层sqlx::query(ROLLBACK TO SAVEPOINT nested_tx).execute(mut*tx).await?;// 释放保存点可选sqlx::query(RELEASE SAVEPOINT nested_tx).execute(mut*tx).await?;// 提交外层事务插入操作生效tx.commit().await?;Ok(())}编译时验证的离线模式默认情况下SQLx 的编译时验证需要连接真实数据库但在 CI/CD 环境或生产环境编译时可能无法访问数据库。此时可使用 SQLx 的离线模式提前生成验证元数据避免编译时依赖数据库。生成离线元数据cargosqlx prepare执行后会生成.sqlx目录目录下包含着所有 SQL 验证的元数据。编译时SQLx 会读取该文件进行验证无需连接数据库。总结随着 Rust 异步生态的不断完善SQLx 也在持续迭代未来将支持更多数据库特性、优化性能、简化使用流程。不过需要注意的是SQLx 的版本还处于 0.x 阶段并没有完全稳定下来有时候会存在一些破坏性更新这点在使用时仍需要注意。

相关文章:

SQLx:一款优秀的异步 SQL 工具库

SQLx:一款优秀的异步 SQL 工具库 传统 ORM 工具会引入冗余抽象,而原生 SQL 操作又容易出现运行时错误。SQLx 作为 Rust 生态中备受推崇的 SQL 工具库,以编译时 SQL 验证为核心卖点,兼顾异步支持、轻量等特性,解决了上述…...

如何高效使用网盘直链解析工具:8大平台全攻略终极指南

如何高效使用网盘直链解析工具:8大平台全攻略终极指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…...

Java的java.lang.StackWalker

Java的java.lang.StackWalker:深入探索堆栈遍历新利器 在Java开发中,堆栈跟踪(Stack Trace)是调试和分析程序行为的重要工具。传统的Throwable::getStackTrace方法存在性能开销大、灵活性不足等问题。Java 9引入的java.lang.Stac…...

通过pg_controldata判断主备库信息

文章目录文档用途详细信息文档用途 1、hghac集群因为网络故障,主备节点都降级为备库,需要通过pg_controldata信息判断原主库,恢复集群。 详细信息 1、数据库服务器执行pg_controldata命令输出控制文件信息 pg_controldata2、服务器1信息输…...

大模型应用核心揭秘:小白也能掌握Agent Skills、Tool与MCP,速收藏!

大模型应用核心揭秘:小白也能掌握Agent Skills、Tool与MCP,速收藏! 大模型应用的核心能力在于内容生成与函数调用。Tool作为Function Call的载体执行任务,MCP协议则统一不同工具接口。Agent Skills是对Tool的进一步封装&#xff…...

Charticulator:微软开源的可视化图表设计工具,让每个人都能创建专业级数据可视化

Charticulator:微软开源的可视化图表设计工具,让每个人都能创建专业级数据可视化 【免费下载链接】charticulator Interactive Layout-Aware Construction of Bespoke Charts 项目地址: https://gitcode.com/gh_mirrors/ch/charticulator 你是否厌…...

从AlexNet到ResNet:图像增广为什么是CV炼丹师的‘基本功’?一个简单实验带你理解

图像增广:从AlexNet到ResNet的泛化密码与实战解码 当你第一次看到卷积神经网络在ImageNet竞赛中超越人类识别准确率时,是否好奇过这些模型究竟如何从有限的数据中学习到如此强大的特征表示?2012年AlexNet横空出世的那个清晨,研究者…...

三相电流测量到底该分立还是集成?从电驱控制实际问题聊起

在做电驱控制的时候,三相电流采样基本是绕不开的一环。很多资料会把重点放在“精度”“带宽”这些参数上,但在实际项目里,真正影响控制效果的,往往不是单一指标,而是——三相电流之间的一致性。尤其是在PMSM FOC控制体…...

别再只盯着IN和LN了!用AdaIN、LIN、AdaLIN玩转图像风格迁移(附PyTorch代码实战)

图像风格迁移中的归一化技术实战:从AdaIN到AdaLIN的深度解析 风格迁移技术近年来在艺术创作、影视特效和设计领域大放异彩,而其中的核心秘密武器之一就是各种归一化技术。当开发者们还在为IN(Instance Normalization)和LN&#xf…...

小白程序员收藏必看:大模型应用开发工程师,开启高薪AI之路!

小白程序员收藏必看:大模型应用开发工程师,开启高薪AI之路! 本文介绍了AI大模型应用开发工程师这一新兴职业,强调其在连接技术与产业中的核心作用。文章解释了该职业与“大模型研发”的区别,指出其专注于利用现有成熟…...

避坑指南:uCharts在UniApp中自定义Y轴刻度与分割数时,你可能遇到的3个问题

避坑指南:uCharts在UniApp中自定义Y轴刻度与分割数的3个典型问题解析 在UniApp中使用uCharts进行数据可视化时,Y轴的自定义配置往往是开发者最常遇到问题的环节。尤其是当我们需要精确控制刻度显示范围、分割数量和小数位精度时,一些看似简单…...

Linux下RTL8852BE无线网卡驱动终极配置与优化指南:告别Wi-Fi 6卡顿问题

Linux下RTL8852BE无线网卡驱动终极配置与优化指南:告别Wi-Fi 6卡顿问题 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be RTL8852BE是一款支持Wi-Fi 6标准的Realtek无线网卡&…...

精准仿真!SOLIDWORKS Simulation 助力电路板随机振动分析与可靠性验证

工程师们,还在为电路板随机振动的设计、仿真难题头疼吗?❌ 电路板振动应力难以精准预判,焊点、元器件失效风险全靠经验,装车 / 上机后才出问题?❌ 摸不准随机振动环境下的结构响应,振动过载导致芯片脱焊、电…...

DSU Sideloader:安全便捷的安卓双系统安装工具

DSU Sideloader:安全便捷的安卓双系统安装工具 【免费下载链接】DSU-Sideloader A simple app made to help users easily install GSIs via DSUs Android feature. 项目地址: https://gitcode.com/gh_mirrors/ds/DSU-Sideloader 还在为刷机风险而担忧吗&…...

PDF文件瘦身革命:如何用pdfsizeopt实现无损压缩与专业优化

PDF文件瘦身革命:如何用pdfsizeopt实现无损压缩与专业优化 【免费下载链接】pdfsizeopt PDF file size optimizer 项目地址: https://gitcode.com/gh_mirrors/pd/pdfsizeopt 你是否曾因PDF文件体积过大而无法通过邮件发送?是否在学术投稿时因文件…...

WinForm容器控件

一 定义容器控件 能装其他控件的控件,就像现实里的「收纳盒 / 抽屉 / 文件夹」,专门用来装按钮、文本框、ListBox 这些 “小控件”。二 用处举个例子:你做登录界面,有 “用户名、密码、登录按钮”3 个控件:不用容器&a…...

[特殊字符]收藏必备!小白程序员转型AI Agent工程师,高薪风口等你来![特殊字符]

🔥收藏必备!小白程序员转型AI Agent工程师,高薪风口等你来!🚀 本文深入分析了AI Agent工程师的巨大潜力,指出其岗位需求迅速增长、薪资远高于传统后端岗位。文章详细介绍了成为AI Agent工程师所需的五大核心…...

5分钟快速搭建微信机器人:WechatBot小白终极指南

5分钟快速搭建微信机器人:WechatBot小白终极指南 【免费下载链接】WechatBot 项目地址: https://gitcode.com/gh_mirrors/wechatb/WechatBot 还在为重复回复微信消息而烦恼吗?想拥有一个24小时在线的智能助手帮你处理日常沟通?Wechat…...

python(环境安装,输入输出,变量)

目录 环境安装 编辑器 安装插件 新建文件 1.代码与文本 输入与输出 hello world 输入输出 练习 字符串 注释 2.数字与变量 1.整数与浮点数 2.变量 今天我们来进行python的学习 和英国人交流,我们需要说英语;和法国人交流,我们需要说法语。 和计算机进行交流,我们也…...

Manus外资收购被叫停:从全球化野心到监管困境,AI创业路在何方?

一个本土创业者的全球化之路 Manus母公司蝴蝶效应的武汉总部,与创始人肖弘母校华中科技大学仅隔一条马路。很长时间里,AI圈提到肖弘常与武汉联系在一起。2024年底,尚未走红的肖弘在圈内已小有名气,不少AI应用创业者推崇他的经营逻…...

IDM无限试用终极指南:告别序列号烦恼的完整解决方案

IDM无限试用终极指南:告别序列号烦恼的完整解决方案 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 还在为Internet Download Manager的"伪造序…...

全面掌握RTL8852BE Wi-Fi 6网卡驱动:Linux用户的终极优化指南

全面掌握RTL8852BE Wi-Fi 6网卡驱动:Linux用户的终极优化指南 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 在Linux系统上获得稳定的Wi-Fi 6连接一直是许多用户面临的挑战&a…...

明冠新材2025年铝塑膜营收8495万元增123%,2026Q1经营现金流转正,固态电池铝塑膜已送样客户

4月27日晚间,明冠新材料股份有限公司(股票代码:688560,股票简称:明冠新材)披露2025年年度报告及2026年第一季度报告。根据公告,公司2025年度实现营业收入7.20亿元,2026年第一季度实现…...

量子最优控制与GRAPE算法在Λ型三能级系统中的应用

1. 量子最优控制基础与GRAPE算法原理1.1 量子最优控制的基本框架量子最优控制的核心目标是设计外部控制场的时间演化形式,使得量子系统在特定时间内从初始态演化到目标态。对于Λ型三能级系统,我们考虑如下控制哈密顿量:$$ H(t) H_0 \sum_{…...

温湿度监控监测样本数据那温湿度阈值怎么设置?报警机制如何启动呢?

​在医疗环境中,温湿度的监控对于保障样本安全、样本质量具有至关重要的作用,合理设置温湿度的上下限阈值,不仅能够及时发现环境异常,还能通过自动报警机制迅速响应,避免潜在风险的扩大。温湿度监控监测样本数据的上下…...

WebGL 开发数字孪生

基于 WebGL 开发数字孪生(Digital Twin)项目已经从简单的“3D 可视化”演变为“全要素实时仿真控制层”。以下是开发 WebGL 数字孪生项目的完整实战流程及技术选型建议:1. 技术选型:WebGL vs WebGPU在 2026 年,虽然 We…...

BetterNCM-Installer:网易云音乐插件一键安装完整指南

BetterNCM-Installer:网易云音乐插件一键安装完整指南 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 想让你的网易云音乐变得更强更好用吗?今天我来给你介绍一…...

别再手动画图了!用evo工具箱5分钟搞定SLAM轨迹评估与可视化(保姆级命令详解)

别再手动画图了!用evo工具箱5分钟搞定SLAM轨迹评估与可视化(保姆级命令详解) 当你完成SLAM算法的初步开发后,最头疼的问题往往不是算法本身,而是如何快速、准确地评估轨迹质量。传统的手动计算误差、用Matlab或Python画…...

Dev Container启动慢、调试卡顿、扩展失效,深度诊断与7步精准修复全流程

更多请点击: https://intelliparadigm.com 第一章:Dev Container性能问题的典型现象与影响面分析 Dev Container 在现代云原生开发中广泛用于环境一致性保障,但其性能瓶颈常被低估。当容器启动缓慢、代码补全延迟显著、或调试会话频繁中断时…...

使用 HookShot 生成高级商品图-霍客引擎

霍客引擎是什么 霍客引擎(HookShot)(https://www.hkshot.com/ )主要服务于亚马逊、淘宝、Shopee、Temu等跨境和国内电商卖家。它利用AI技术,帮商家快速做出高质量的主图、详情页、短视频、场景图和模特图等电商素材,支持30主流电…...