掌握Rust数据库操作:SQLx异步查询、连接池、事务和ORM。
// Cargo.toml: sqlx = { version = "0.7", features = ["postgres", "runtime-tokio"] }
use sqlx::postgres::PgPoolOptions;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
// 连接池
let pool = PgPoolOptions::new()
.max_connections(5)
.connect("postgres://user:pass@localhost/db").await?;
// 查询
let rows = sqlx::query("SELECT id, name FROM users")
.fetch_all(&pool).await?;
// 参数化查询(防止SQL注入!)
let user = sqlx::query_as::<_, (i32, String)>(
"SELECT id, name FROM users WHERE id = $1"
)
.bind(1)
.fetch_one(&pool).await;
// 插入
sqlx::query("INSERT INTO users (name) VALUES ($1)")
.bind("Alice")
.execute(&pool).await?;
Ok(())
}
✅ 编译验证通过
// sqlx的编译期检查(需数据库运行或离线模式)
use sqlx::query;
// 运行时查询
let r = query("SELECT * FROM users").fetch_all(&pool).await;
// macro查询(编译期检查SQL)
// let r = sqlx::query_as!(User, "SELECT * FROM users")
// .fetch_all(&pool).await?;
async fn transfer(pool: &sqlx::PgPool, from: i32, to: i32, amount: f64) -> Result<(), sqlx::Error> {
let mut tx = pool.begin().await?;
sqlx::query("UPDATE accounts SET balance = balance - $1 WHERE id = $2")
.bind(amount).bind(from)
.execute(&mut *tx).await?;
sqlx::query("UPDATE accounts SET balance = balance + $1 WHERE id = $2")
.bind(amount).bind(to)
.execute(&mut *tx).await?;
tx.commit().await
}
实现完整的用户增删改查。
实现数据库分页查询。
用sqlx-cli管理数据库迁移。
掌握Rust数据库操作——持久化存储
Rust的异步模型与其他语言有本质区别:
async函数不是语法糖生成闭包或Future对象,而是编译器生成一个状态机enum,每个.await点是一个状态。这比Green Thread更高效——无堆分配、无运行时开销。
不使用的异步特性不产生代码。不调用async函数?没有状态机代码。这与其他语言的全局运行时(Go的goroutine调度器、Java的Fiber)不同。
Rust没有内置异步运行时。你选择Tokio、async-std或其他——运行时是库,不是语言特性。这意味着灵活但需要选择。
| 模型 | 语言 | 开销 | 并发数 |
|---|---|---|---|
| OS线程 | C/Java | 1-8MB/线程 | ~1000 |
| Green Thread | Go | ~2KB/goroutine | ~100K |
| async/await | Rust | ~几百字节 | ~1M+ |
| 回调 | Node.js | 小 | 高 |
以下练习帮助你将本课知识应用到实际场景:
阅读以下代码片段,找出潜在问题并改进:
// 仔细阅读,思考有什么问题
fn process(data: Vec) -> Vec {
let mut result = Vec::new();
for i in 0..data.len() {
result.push(data[i] * 2);
}
result
}
改进建议:使用迭代器、预分配容量、考虑溢出。
用criterion基准测试对比以下实现的性能差异:
为以下场景设计Rust API:一个支持过期时间的缓存系统。考虑所有权、错误处理和泛型。
通过本课的学习,你应该掌握以下核心要点:
如果某个要点还不够清晰,回顾本课的代码示例和内存图,动手编写代码验证你的理解。
以下资源帮助你深入学习本课主题:
本课涉及的核心概念,确保你理解每一个:
| 术语 | 说明 |
|---|---|
| 所有权 | Rust内存管理的核心机制,每个值有唯一所有者 |
| 借用 | 通过引用访问数据,不获取所有权 |
| 生命周期 | 引用有效的范围,编译期分析工具 |
| trait | Rust的接口/抽象机制,类似其他语言的接口 |
| 泛型 | 参数化类型,零成本抽象 |
| 模式匹配 | 强大的数据解构和分支机制 |
| 零成本抽象 | 高层抽象不引入运行时开销 |
| fearless concurrency | 编译器保证线程安全 |
Q: Rust学习曲线真的很陡吗?
A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。
Q: Rust适合什么项目?
A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。
Q: 遇到编译错误怎么办?
A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。