Rust SQLx 入门:轻松操作多种数据库

deer332025-09-12技术文章28

什么是 SQLx?

SQLx 就像是数据库世界的"万能翻译器"。它不需要复杂的ORM学习曲线,而是让你直接使用SQL语句,同时提供以下优点:

  • 编译时检查:在写代码时就能发现SQL错误,而不是等到运行时
  • 纯Rust编写:无需依赖C库,安装简单
  • 异步支持:适合高性能网络应用
  • 多数据库支持:一套代码适配多种数据库

快速开始

首先,在项目的 Cargo.toml文件中添加依赖:

[dependencies]
sqlx = { version = "0.7", features = ["runtime-tokio-native-tls", "postgres"] }
tokio = { version = "1.0", features = ["full"] }

这里以 PostgreSQL 为例,如果你想用其他数据库,只需将 "postgres" 替换为 "mysql"、"sqlite" 或 "mssql"。

基础使用:四步上手

1. 连接数据库

use sqlx::postgres::PgPoolOptions;

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    // 创建数据库连接池
    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect("postgres://用户名:密码@localhost/数据库名")
        .await?;
    
    println!("数据库连接成功!");
    Ok(())
}

2. 创建数据表

// 创建用户表
sqlx::query(
    "CREATE TABLE IF NOT EXISTS users (
        id SERIAL PRIMARY KEY,
        name VARCHAR NOT NULL,
        email VARCHAR NOT NULL
    )"
)
.execute(&pool)
.await?;

3. 插入数据

// 插入新用户
let result = sqlx::query(
    "INSERT INTO users (name, email) VALUES ($1, $2)"
)
.bind("张三")
.bind("zhangsan@example.com")
.execute(&pool)
.await?;

println!("插入了 {} 行数据", result.rows_affected());

4. 查询数据

// 查询所有用户
#[derive(Debug)]
struct User {
    id: i32,
    name: String,
    email: String,
}

let users = sqlx::query_as::<_, User>("SELECT id, name, email FROM users")
    .fetch_all(&pool)
    .await?;

for user in users {
    println!("用户: {:?}", user);
}

多数据库适配技巧

SQLx 最强大的功能之一就是可以用相似的方式操作不同的数据库。下面是一个简单的示例:

// 根据使用的数据库自动调整SQL语法
let user_count: i64 = sqlx::query_scalar(
    "SELECT COUNT(*) FROM users WHERE name LIKE $1"
)
.bind("%张%")
.fetch_one(&pool)
.await?;

println!("找到 {} 个姓张的用户", user_count);

这段代码在 PostgreSQL 中使用 $1作为参数占位符,在 MySQL 和 SQLite 中会自动使用 ?,你不需要手动修改。

实用小技巧

1. 事务处理

let mut transaction = pool.begin().await?;

// 在事务中执行多个操作
sqlx::query("INSERT INTO users (name, email) VALUES ($1, $2)")
    .bind("李四")
    .bind("lisi@example.com")
    .execute(&mut transaction)
    .await?;

// 提交事务
transaction.commit().await?;

2. 错误处理

match sqlx::query("INSERT INTO users (name, email) VALUES ($1, $2)")
    .bind("王五")
    .bind("wangwu@example.com")
    .execute(&pool)
    .await
{
    Ok(result) => println!("插入成功,影响行数: {}", result.rows_affected()),
    Err(e) => println!("插入失败: {}", e),
}

为什么选择 SQLx?

  1. 简单直观:直接使用SQL,学习成本低
  2. 安全可靠:编译时检查SQL语法,减少运行时错误
  3. 灵活高效:既支持简单查询,也支持复杂操作
  4. 生态丰富:与Rust异步生态完美融合

总结

SQLx 让数据库操作变得简单而愉快。无论你是初学者还是有经验的开发者,都可以轻松上手。你不需要为了不同的数据库学习不同的API,一套代码就能搞定多种数据库。