Rust如何操作数据库
作为一个Rust新手,想请教大家在实际项目中如何用Rust操作数据库?目前了解到有Diesel和SQLx这样的ORM和查询构建器,但不太清楚它们的优缺点和适用场景。比如:
- 在开发Web应用时推荐使用哪个库?
- 这两种方式在性能和使用体验上有什么主要区别?
- 是否有其他更轻量级的数据库操作方案?
- 能否分享一些实际项目中的最佳实践和常见坑点? 希望有经验的前辈能指点迷津,最好能附带简单的代码示例说明基本用法。
2 回复
Rust操作数据库常用库:
- Diesel - ORM框架,类型安全,支持PostgreSQL、MySQL、SQLite
- SQLx - 异步驱动,编译时检查SQL,支持多种数据库
- tokio-postgres - 纯异步PostgreSQL客户端
示例(Diesel):
// 查询用户
let users = users::table.filter(name.eq("张三")).load::<User>(&conn)?;
建议:根据数据库类型和同步/异步需求选择合适库。
在Rust中操作数据库主要通过以下几种方式:
1. 使用数据库驱动库
SQLite
use rusqlite::{Connection, Result};
fn main() -> Result<()> {
let conn = Connection::open("test.db")?;
// 创建表
conn.execute(
"CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)",
[],
)?;
// 插入数据
conn.execute(
"INSERT INTO users (name) VALUES (?1)",
&["Alice"],
)?;
// 查询数据
let mut stmt = conn.prepare("SELECT id, name FROM users")?;
let users = stmt.query_map([], |row| {
Ok((row.get::<_, i32>(0)?, row.get::<_, String>(1)?))
})?;
for user in users {
let (id, name) = user?;
println!("User {}: {}", id, name);
}
Ok(())
}
PostgreSQL
use postgres::{Client, NoTls};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
client.batch_execute("
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL
)
")?;
client.execute(
"INSERT INTO users (name) VALUES ($1)",
&[&"Bob"],
)?;
for row in client.query("SELECT id, name FROM users", &[])? {
let id: i32 = row.get(0);
let name: &str = row.get(1);
println!("User {}: {}", id, name);
}
Ok(())
}
2. 使用ORM框架 - Diesel
Diesel是Rust中最流行的ORM框架:
// Cargo.toml 依赖
// diesel = { version = "2.0", features = ["postgres"] }
use diesel::prelude::*;
// 定义模型
#[derive(Queryable, Insertable)]
#[diesel(table_name = users)]
struct User {
id: i32,
name: String,
}
// 插入数据
fn create_user(conn: &mut PgConnection, name: &str) -> QueryResult<User> {
use crate::schema::users;
let new_user = NewUser { name };
diesel::insert_into(users::table)
.values(&new_user)
.get_result(conn)
}
// 查询数据
fn get_users(conn: &mut PgConnection) -> QueryResult<Vec<User>> {
users::table.load::<User>(conn)
}
3. 异步数据库操作 - sqlx
use sqlx::postgres::PgPoolOptions;
#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
let pool = PgPoolOptions::new()
.connect("postgres://user:pass@localhost/db")
.await?;
// 查询
let rows = sqlx::query!("SELECT id, name FROM users WHERE id = $1", 1)
.fetch_all(&pool)
.await?;
// 插入
sqlx::query!("INSERT INTO users (name) VALUES ($1)", "Charlie")
.execute(&pool)
.await?;
Ok(())
}
主要库推荐
- sqlx: 异步、编译时检查的SQL查询
- Diesel: 功能完整的ORM框架
- rusqlite: SQLite驱动
- tokio-postgres: 异步PostgreSQL驱动
- mysql: MySQL驱动
选择哪种方式取决于项目需求:需要异步操作选sqlx,需要完整ORM功能选Diesel,简单项目可直接使用数据库驱动。

